Hello, I’m Karsong.
There’s a guy who’s been popping up a lot in front of framework tweets lately.
I thought, “Brother who are you?”
It turns out to be a framework author, whose work is called SolidJS.
Flipping through the frame, this sentence caught my attention:
Support for modern front-end features such as: JSX, Fragments, Context, Portals, Suspense, Streaming SSR, Progressive Tells, Error Boundaries and Concurrent Rendering
I assume you’re not the React Princess? It’s not like React, it’s exactly the same, right?
As a traditional Chinese, adhering to the idea, I tried a day, and looked at the source code, the results found that this framework is really a treasure frame.
This article will compare the similarities and differences between SolidJS and React and explain its unique advantages. After reading it, I wonder if you will express the same sigh with me:
This is like a React. React. React.
After reading this article, you will not only know the new framework, but also have a better understanding of React.
On the whole!
At first glance, it looks similar
Let’s look at the React syntax differences from a counter example:
import { render } from "solid-js/web";
import { createSignal } from "solid-js";
function Counter() {
const [count, setCount] = createSignal(0);
const increment = () = > setCount(count() + 1);
return (
<button type="button" onClick={increment}>
{count()}
</button>
);
}
render(() = > <Counter />.document.getElementById("app"));
Copy the code
React differs from React:
-
UseState became createSignal
-
React changes from using count directly to calling a method: count()
Is it just a React framework?
Don’t worry, let’s take a look at compile time, run time, and response principles.
Compile time is very different
React’s compile time is thin and basically just compiles JSX syntax.
SolidJS takes a similar approach to Svelte: state updates are compiled as separate DOM manipulation methods at compile time.
What’s the good of that? There are two main points.
Volume advantage under certain conditions
You don’t have to pay for code you don’t use
When using React, the code appears in the final compiled code even if Hooks are not used.
In SolidJS, unused functionality does not appear in compiled code.
For example, in the timer example above, the compiled code has a line like this:
delegateEvents(["click"]);
Copy the code
The purpose of this line of code is to register the Click event agent on document.
If onClick was not used in the timer, this line would not be in the compiled code.
Compare the volume difference between the source code and the compiled code of Svelte and React, which are similar compile-time solutions.
The horizontal axis represents source code volume, the vertical axis represents compiled code volume, the red line represents Svelte, and the blue line represents React:
It can be seen that the compile-time scheme has a volume advantage up to the critical value (business source code volume reaches 120KB).
Because SolidJS uses JSX to describe views and is more flexible than Svelte using vUe-like template syntax, it does not achieve the same extreme compilation optimization as Svelte at compile time, making it a bit heavier than Svelte runtime.
This gives him an added benefit: SolidJS’s code size is about 25% smaller than Svelte’s in a real project (> 120KB).
That’s a blessing in disguise, isn’t it?
Faster update speed
We know that React and Vue have a virtual DOM layer (called Fiber tree in React).
Whenever an update occurs, the virtual DOM is compared (Diff algorithm), and the results of the comparison perform different DOM operations (add, delete, modify).
However, SolidJS and Svelte can directly call the compiled DOM operation method when the update occurs, saving the time consumed in the step of virtual DOM comparison.
For example, in the timer above, when clicked, the call stack from triggering updates to view changes is as follows:
Trigger events, update status, update views, call all the way through, clear and clear.
The React call stack looks like this:
Left, middle and right red, green and blue box call stacks correspond to:
-
Handle events
-
Compare and generate Fiber tree
-
Perform DOM operations based on the comparison results
As you can see, the update path for SolidJS is much shorter than React.
Why, you ask? This also has to start from its special response principle.
Principle of response
Suppose we have a state name with an initial value of KaSong. We want to render a div based on name.
SolidJS compiled code looks like this:
const [name, setName] = createSignal("KaSong");
const el = document.createElement("div");
createEffect(() = > el.textContent = name());
Copy the code
CreateEffect is similar to useEffect of React.
Because it relies on name in its callback, the createEffect callback is triggered when name changes, changing el.textContent and causing DOM updates.
React like:
useEffect(() = > {
el.textContent = name;
}, [name])
Copy the code
First screen rendering result:
<div>KaSong</div>
Copy the code
Next, trigger the update:
setName("XiaoMing")
Copy the code
Updated results:
<div>XiaoMing</div>
Copy the code
Why is createEffect triggered when name is updated?
There’s no dark magic here, just subscribe to publish.
The createEffect callback depends on name, so it subscribes to changes in name.
Due to limited space, I’ll talk about the details next time.
The key here is that SolidJS state is atomic.
That is, states have dependencies on each other, and they form a local dependency graph. When you change one state, other states in the dependency diagram change as well.
If these dependencies are used in createEffect, their changes are subscribed to.
When the state changes, the createEffect callback is executed, which in turn executes specific DOM methods to update the view.
The true. Response type update, refers to which dozen which, Li Yunlong call expert.
Some students will ask, Isn’t React like that?
Let me ask you a question:
Why do Hooks require that the order of calls be fixed?
Why do useEffect callbacks have closure issues?
The answer is clear: React can only be responsive within these constraints.
Work hard React
Here’s a potentially counterintuitive lesson: React doesn’t care which component triggered the update.
In React, any component triggers an update (such as a call to this.setState) and all components go through the process again. You need to build a new Fiber tree.
To reduce render nonsense, there are optimization strategies in React that determine whether components can reuse the last updated Fiber node (thus skipping render).
There are also apis (useMemo, PureComponent…) Let the developer tell him which components can skip Render.
If we say that the SolidJS update process is like a painter, where the picture needs to be updated, just draw a few strokes.
Then the update process of React is like a person taking a photo with a camera, finding the difference between the photo and the last one, and finally updating the different parts.
conclusion
Today, we talked about the differences between SolidJS and React, mainly reflected in three aspects:
-
Compile time
-
The runtime
-
Principle of response
Do you like this one: no Hooks order restrictions, no useEffect closure issues, no Fiber tree, React better framework than React?
If you ask me which one? Of course, I’ll take whichever pays better.