The title of the article may seem a little flashy, however, like the Svelte framework itself and the ideas behind it. If you still do not know anything about Svelte, buckle up, now we rush towards the revolution.
Note that this is not a lesson to get started with Svelte. There is already a great step by step interactive guide from the Svelte team that will immerse you in the world of reactive programming.
Disclaimer: I am not a rock star in programming and I do not know everything in the world. I'm just enthusiastic about new trends that happen every day, and I like when I can, talk about them - this is how this article appeared. Treat it critically and be sure to let me know if I wrote something ridiculous.
Ok, now let's dive into the topic!
Before telling me why I think Svelte will break everyone, let's take a look at this recent tweet from a man named Dan, and try to understand what he meant:
Hmm, why is it then called React?
Another caveat: this article is in no way intended to criticize React. I decided to use it as an example, because most people who read this article dealt with React at one time or another in their lives. Just now this is the best example for opposing Svelte.
What did Dan mean, and how did that affect the way we write code now? To answer these questions, let me tell you in a simplified way how React works under the hood.
When a React application is being rendered, a copy of the DOM is placed in a structure called Virtual DOM . This virtual DOM mediates between your React code and what the browser displays in the DOM.
Then, when the data changes (for example, after calling this.setState
or useState
), React does a little work to determine which parts of the application need to be redrawn.
It compares the virtual DOM with the real one to determine what has changed since the data was updated. It then redraws only those parts of the DOM that have differences in the virtual DOM, eliminating the need to redraw the whole DOM every time for any change.
Everything happens very quickly, because updating a virtual DOM is much cheaper than a real one, and React updates only the necessary pieces of a real DOM. This article explains this process much better.
You probably noticed one feature. If you do not tell React that the data has changed (by calling this.setState
or an equivalent hook), the virtual DOM will not change, and no response will follow from React (ta-dam!).
That's what Dan meant when he said that React is not fully reactive. React relies on the fact that you independently monitor the data of your application and report on their changes. This adds to your work.
Svelte is a completely new way to create web applications in an incredibly fast, efficient and truly responsive way. And all this without using a virtual DOM and with fewer lines of code than would be needed in another framework or library.
This all sounds great, of course, but how does it differ from many other JavaScript libraries and frameworks? - you ask. I will tell.
Svelte is not a library. Svelte is not a framework. Rather, Svelte is a compiler that gets your code and produces native JavaScript, which directly interacts with the DOM without the need for any intermediary.
Wait wait what Compiler? Yes - compiler. And this is a damn good idea, I can not understand why it has not been so obvious so far. Further I will tell why I consider it very cool.
Here is a quote from the Rich Harris report at the YGLF 2019 conference:
Svelte 3.0 takes reactivity from the API component to the language itself.
What does this mean? Well, we already know that React (and most other frameworks) require you to use an API to tell it about data changes (call this.setState
or useState
) and write their virtual DOM.
The need to call this.setState
in React (and other UI frameworks and libraries) means that the reactivity of your application is now tied to a specific API, without which it will know nothing about changes in data at all.
Svelte takes a different approach.
His code execution was inspired by the way Observable does it. Instead of running the code from top to bottom, it is executed in topological order. Let's look at the code snippet below and analyze what it means to run it in topological order.
1. (() => { 2. let square = number => number * number; 3. 4. let secondNumber = square(firstNumber); 5. let firstNumber = 42; 6. 7. console.log(secondNumber); 8. })();
When executing this code from top to bottom, an error will be shown in line No. 4, because the secondNumber
uses the value firstNumber
, which at this point has not yet been initialized.
If you run this code in topological order, there will be no errors. How so? The compiler will not run this code from top to bottom, but will consider all variables in the code and generate a dependency graph (that is, who depends on whom initially).
The extremely simplified compiler path, with the topological passage of our example, looks like this:
1. 'square' ? - , 2. 'secondNumber' ? - 'square' 'firstNumber'. 'square', 'firstNumber', . 3. , 'firstNumber'. 'secondNumber' 'square' 'firstNumber' - , 'console.log'? - , .
At first glance, the code seems to work from top to bottom, but if you look closely, you will notice that this is not the case.
When the compiler reaches line 4, it detects that it does not have the firstNumber
, so it pauses further execution and scans all the code, looking for the initialization of this variable. Well, this is exactly what happens in line No. 5, so first line No. 5 is executed, and then the execution of the code will return to line No. 4 and go on.
Briefly: provided that expressionA
depends on expressionB
, expressionB
will be executed first regardless of the order in which these expressions are declared.
So how does this relate to how Svelte realizes its real reactivity? You can mark any JavaScript expression with a special label . It looks like this: $: foo = bar
. That is, all that needs to be done is to add a label with the name $
before the expression foo = bar
(in strict mode, this will not work if foo
not been defined previously).
So, when Svelte sees any expression with the $:
prefix, it knows that the variable on the left receives its value from the variable on the right. Now we have a way to bind the value of one variable to the value of another.
This is reactivity! Right now, we used part of the standard JavaScript API itself to achieve true reactivity without having to bother with third-party APIs like this.setState
.
Here is how it looks in practice:
1. // js 2. let foo = 10; 3. let bar = foo + 10; // bar 20 4. foo = bar // bar 20 ( ) 5. bar = foo + 10 // bar 30 6. // svelte js 7. let foo = 10; 8. $: bar = foo + 10; // bar 20 9. foo = 15 // bar 25, foo
Note that in this example we did not need to recalculate the bar
with the new value of foo
, either directly or by re-execution bar = foo + 10
, or by calling an API method like this.setState ({bar = foo + 10})
. This is done automatically.
That is, when you change foo
to 15
, bar
automatically updates to 25
, and you don’t need to call any API to do this. Svelte already knows everything.
Part of the compiled Javascript code in the above example looks like this:
1. //... 2. function instance($$self, $$props, $$invalidate) { 3. let foo = 10; // bar 20 4. $$invalidate('foo', foo = 15) // bar 25, foo 5. let bar; 6. $$self.$$.update = ($$dirty = { foo: 1 }) => { 7. if ($$dirty.foo) { $$invalidate('bar', bar = foo + 10); } 8. }; 9. return { bar }; 10. } 11. //...
Take your time to read further, study this code snippet. Leisurely.
Notice that the foo
value is updated before the bar
is declared? This is because the compiler analyzes the Svelte code in topological order, and not line by line from top to bottom.
Svelte responds independently to changes in data. You do not need to keep track of what is changing and when - it happens by itself.
Note: In line # 4, the bar
value will not be updated until the next iteration of the EventLoop loop clears all tails.
Thus, we no longer need to worry about manually updating the state when data changes. You can think all day about the logic of the application, while Svelte is in charge of matching the UI with the current state.
Remember, I previously wrote that Svelte allows you to do more, while writing fewer lines of code? I will show a simple component in React and its equivalent in Svelte, and you will see for yourself:
17 lines of code against 29
These two applications are completely identical in functionality, but you can see how much code we needed to write in React.js - and don't even ask me to do this in Angular.
I am the oldest developer
Apart from the fact that the Svelte code is more pleasing to the eye, it is also much easier to understand because it has fewer structures. For example, we do not need an event handler to update the value of a text field — simply bind.
Imagine you just started learning web development. Which code would be less clear to you? The one on the left, or the one on the right?
While this may seem obvious, it quickly becomes clear how much more useful to write fewer lines of code when you start building larger and more complex applications. I personally spent hours trying to understand how a large React component works, which was written by my colleague.
I truly believe that such a simplified API in Svelte will allow us to read and understand the code much faster, improving our overall productivity.
Well, we saw that Svelte is truly reactive and allows you to do more with less effort. How about performance? And how convenient are applications written entirely in Svelte?
One of the reasons why React is so powerful is that it uses a virtual DOM to make it possible to redraw the user interface of an application in small pieces, eliminating the need to redraw the entire DOM every time something changes (which is really very expensive).
However, the disadvantage of this approach is that if the data of the component changes, the React will redraw not only the component itself, but also all its children, regardless of whether they have changed or not. That is why API methods such as shouldComponentUpdate
, useMemo
, React.PureComponent
, etc. exist in React.
This problem will always occur when using the virtual DOM to draw the user interface when the state of the application changes.
Svelte does not use virtual DOM, but how then does it solve the problem of redrawing DOM according to new state data? Well, let me again quote Rich Harris from his wonderful performance on YGLF:
Frameworks are not tools for organizing your code. These are tools for organizing your mind.
This thought led to the idea that the framework could be something that works even at the stage of building the application, thus eliminating the need for your code to have an intermediary in runtime. Thanks to this idea, Svelte became a compiler, not a framework.
This simple idea also explains why Svelte is very fast. Svelte compiles your code into efficient low-level Javascript, which interacts directly with the DOM. This is all fine, but how does Svelte solve the problem of re-rendering the entire DOM entirely when data changes?
The difference is in how traditional frameworks (for example, React) and Svelte find out that something has changed in the state. We have already discussed that it is necessary to call the API method in React to inform it when the data changes. In the case of Svelte, it is sufficient to simply use the assignment operator =
.
If the value of a state variable — say, foo
— is updated with the operator =
, Svelte, as we already know, will update all other variables that depend on foo
. This allows Svelte to redraw only those parts of the DOM that somehow get their value from foo
.
I will not describe the actual implementation of this process, because this article is already quite voluminous. But you can see how Rich Harris himself talks about it.
Svelte 3.0 is one of the best things that has appeared in the field of web development lately. Some may call it exaggeration, but I disagree. The concept of Svelte and its implementation allows us to create large applications, while sending less Javascript code to the user's browser.
It also allows applications to be more efficient, more lightweight and at the same time get the code that is easier to read. So will Svelte be able to replace React, Angular or any other traditional UI framework in the near future?
While I answer - no. Svelte is too young compared to them, so he needs time to grow up, grow up and figure out some quirks that we do not even suspect yet.
Just as React has redefined the development of web applications with its appearance, Svelte also has the potential to change our understanding of frameworks and perhaps the whole process of thinking when creating applications.
Happy coding!
Source: https://habr.com/ru/post/453458/
All Articles