头图

SolidJS said stiffly: I am more react than React

卡颂
中文

Hi everyone, this is Kasong.

Recently, an old man often appeared under related tweets front-end frame.

一副憨厚的样貌

I thought: "Brother, who are you?"

After checking, it turned out to be a framework author, and his work is called SolidJS .

Looking through the framework introduction, this sentence successfully attracted my attention:

Support modern front-end features, such as: JSX, Fragments, Context, Portals, Suspense, Streaming SSR, Progressive Hydration, Error Boundaries and Concurrent Rendering

I wonder if you are the React , right? This cannot be said to React similar to 060e2ed442c1a9, but it can only be said to be exactly the same, right?

As a traditional Chinese people, adhering to To have come thought, I tried one day and looked at the source code and found that the framework is really a treasure frame.

This article will compare SolidJS and React , and explain his unique advantages. After reading it, I don’t know if you will sigh the same as me:

This is simply more react than React (react is translated as response)

I believe that after reading this article, I will not only know a new framework, but also have a deeper understanding React

Open!

At first glance very similar

Let us take a counter example to see the difference React


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"));

Different from React

  • useState renamed createSignal
  • Obtain count status from React count directly to use method call, namely: count()

Is it just a framework of React

But wait, let's compile time , running , response principle three areas to look at.

Big difference at compile time

React compiled when it thin , basically just compile JSX syntax.

And SolidJS adopts a Svelte : when compiling, the status update is compiled into an independent DOM operation method.

What are the benefits of doing this? There are two main points.

Volume advantage under certain conditions

You don’t need to pay for the code you don’t use

Use React , even if not used Hooks , its code will appear in the code after the final compilation.

In SolidJS , unused functions will not appear in the compiled code.

For example, in the timer example above, the compiled code has a line like this:

delegateEvents(["click"]);

The purpose of this line of code is in document registered on click event broker.

onClick is not used in the timer, there will not be this line in the compiled code.

A similar comparison enthusiastic users compile-time program Svelte and React between source and the compiled code volume differences.

The horizontal axis represents the source code volume, the vertical axis represents the compiled code volume, the red line represents Svelte , and the blue represents React :

It can be seen that before the critical value (the volume of business source code reaches 120kb), the compile-time program has a certain volume advantage.

Because SolidJS uses JSX describe the view, it is Svelte using a template syntax similar to Vue , so it is impossible to achieve the same extreme compilation optimization as Svelte at compile time, making it a bit heavier Svelte

This brings additional benefits for him: in a real project (> 120kb) in, SolidJS code size than Svelte about 25% smaller.

Really, a blessing in disguise?

Faster update speed

We know that in React with Vue there is a layer of virtual the DOM ( React the call Fiber tree).

Whenever an update occurs, the virtual DOM will be compared ( Diff algorithm), and the result of the comparison will perform different DOM operations (addition, deletion, modification).

When the SolidJS and Svelte are updated, the compiled DOM operation method can be directly called, which saves the time consumed by virtual DOM comparison

For example, the timer above, when clicked, the call stack from trigger update to view change is as follows:

Trigger events, update status, update view, call all the way to the end, clear and clear.

The same example is placed in React , the call stack is as follows:

The call stacks of the left, middle and right red, green, and blue boxes correspond to:

  • Handling events
  • Compare and generate Fiber tree
  • Perform operation DOM according to the comparison result

Visible, SolidJS update path than React much shorter.

Why do you ask? This has to start with its special response principle .

Response principle

Suppose there is a state name , the initial value is KaSong . We hope according to name render a div .

The compiled code of SolidJS

const [name, setName] = createSignal("KaSong");

const el = document.createElement("div");
createEffect(() => el.textContent = name());

Among them, createEffect similar to the React of useEffect .

Because its callback relies on name , when name changed, the createEffect callback will be triggered, changing el.textContent , resulting in DOM update of 060e2ed442c741.

Similar to React :

useEffect(() => {
  el.textContent = name;
}, [name])

First screen rendering result:

<div>KaSong</div>

Next, trigger the update:

setName("XiaoMing") 

Results after update:

<div>XiaoMing</div>

Why does name trigger after createEffect ?

There is no black magic here either, that is subscribe to publish .

createEffect callback depends on name , so it will subscribe to the changes of name

Due to limited space, let's talk about the implementation details next time.

The key here is that, SolidJS state having atomic .

That is, the states have a dependency relationship with each other, and they form a partial dependency graph. When one state is changed, other states in the dependency graph will also change.

createEffect , they will be subscribed to their changes.

When the state changes, the createEffect callback will be executed, and then the specific DOM method will be executed to update the view.

true . responsive update 160e2ed442c8be, which refers to which one to play, Li Yunlong directly

Some students may ask, is this not true for React

Let me ask you a question:

Why does Hooks that the calling sequence cannot be changed?

Why does the useEffect callback have closure problems?

The answer is already here: React can only achieve response under these restrictions.

Hard work React

There is a possibly counter-intuitive knowledge: React does not care which component triggered the update.

In React , any component triggers an update (for example, calling this.setState ), all components will go through the process again. Because it needs to build a new Fiber tree.

In order to reduce the meaningless render , React are some optimization strategies in 060e2ed442c999 to determine whether the component can reuse the last updated Fiber node (thus skipping render ).

At the same time, it also provides a lot of API (for example: useMemo , PureComponent ...), let the developer tell him which components can skip render .

If you say that SolidJS is like a painter, you can draw a few strokes wherever you need to update on the screen.

Then React is like a person taking a photo with a camera, then taking this photo and the last photo to find the difference, and finally updating the different places.

to sum up

Today, we talked about SolidJS and React , which are mainly reflected in three aspects:

  • Compile time
  • Runtime
  • Response principle

I don’t know if you like this one: there is no Hooks order restriction, no useEffect closure problem, no Fiber tree, and a framework that is more react React

If you ask me which one to choose? Of course, I will use whichever one gives the higher salary.

阅读 11.6k
avatar
卡颂
《React技术揭秘》作者
2.3k 声望
16.4k 粉丝
0 条评论
avatar
卡颂
《React技术揭秘》作者
2.3k 声望
16.4k 粉丝
文章目录
宣传栏