Choice of front-end future framework

foreword

The three major frameworks we are familiar with, from vue's responsive virtual dom processing, to react's fiber architecture under the asynchronous update rendering of virtual dom processing, to angular's independently designed dom update strategy, dependency injection, etc. Next, I will briefly describe the future framework and development of the front-end.

The characteristics of the three frameworks

Declarative, virtual DOM, componentization

The three frameworks of react, angular, and vue are similar in that they define our loops and displays in templates declaratively, and we don't need to modify dom imperatively. We no longer consider the original dom update strategy, we use the comparison between the virtual dom and the real dom, making it very useful for on-demand update nodes in large scenarios. At the same time, the frameworks are all oriented to component-based development, and we can solve the problem of code reuse more efficiently.

Front-end framework trends

image.png

We can see that there are three compilation phase frameworks with obvious trends, Svelte, Solid, and Qwik.

Svelte front-end framework

Svelte's language is very similar to native js, and its performance is no different from that of native js. Svelte solves the performance problem of virtual dom comparison at the runtime level of the framework when the multiplexing nodes are not so needed. We can directly compile Real dom processing. The core is the static analysis compiler, which lets us know which variable changes and just update the nodes as needed. Let's look at the specific usage of Svelte:

<script>
  let count = 0;
  const increment = () => {
    count += 1;
  };
</script>

<button on:click={increment}>
  count is {count}
</button>

Let's see what is the content after compilation

image.png

We can see in the block, in fact, the p function is to update the value, the c function is to create dom, and the d is to uninstall dom. In essence, Svelte actually helps us achieve declarative processing. So how do we monitor data changes? Svelte actually uses the compiler to detect variable assignments, updates, and changes. Once a change is detected, the corresponding changed code fragment will be executed immediately.

Solid front-end framework

Solid is written more like react, the biggest difference is that there is no virtual dom, and at the same time, it has a one-way data flow like react. We simply start a Solid template project through vite. After the local service runs, we can see that it looks like this before compiling

import { createSignal } from 'solid-js'
import './App.css'

function App() {
  const [count, setCount] = createSignal(0)

  return (
    <div class="card">
      <button onClick={() => setCount((count) => count + 1)}>
        count is {count()}
      </button>
      <p>
        hello solid !
      </p>
    </div>
  )
}

export default App

image.png

After compiling, we obviously found that the static html string is passed in through the template and then the real dom is returned, and then it can be quickly matched to different node positions, the click event is bound to el2, and the text node is inserted in $insert.

那么solid是怎么监听然后更新模板的dom元素呢,答案是我们代码的createSignal方法

信号 Signal

Solid的createSignal是一种函数式编程范式,其基本原理是返回一个数组,包含一个getter函数和一个setter函数。其主要用途是实现响应式数据流,即当setter函数更新数据时,会自动触发与之相关的视图更新。

具体来说,createSignal会创建一对getter和setter函数,getter函数用于获取当前数据值,setter函数用于更新数据值,并通知所有监听该数据的视图进行更新。Solid在内部使用了一些技术(如ES6的Proxy)来实现数据的响应式更新,保证了视图和数据的实时同步。

除了createSignal外,Solid还提供了一些响应式编程相关的API,如createMemo、createEffect等,用于实现类似Vue.js的单向数据流和响应式UI更新。

Qwik 全栈框架

Qwik主要解决了在服务端渲染的dom,在客户端也要修改它返回渲染的dom(这个过程为水合也就是hyration),客户端同时会去比对服务端的dom结构,并对代码做重新渲染,那么同一代码片段渲染了两次的性能损耗是很大的问题。

Qwik的做法是将全部的渲染逻辑放在了服务端,那么我们在页面如何做交互呢,控制服务端返回的字符串渲染动态的的dom呢,答案是Qwik直接编译出不同的代码片段,我们每一个行为,比如你定义的click事件,他会单独生成一个js文件,用户在触发这个事件后,我们可以直接请求服务端获取click的代码片段。所以Qwik会产出大量的交互的js文件,所以他是细粒度的按需加载。

我们看下具体的用法:

import { component$, useSignal } from '@builder.io/qwik'
import './app.css'

export const App = component$(() => {
  const count = useSignal(0)

  return (
    <>
      <h1>Vite + Qwik</h1>
        <button onClick$={() => count.value++}>count is {count.value}</button>
    </>
  )
})

image.png

我们在渲染静态dom的入口看看,这是一个类似react的createElement的编译函数。我们可以看到这个事件方法的文件是懒加载的,我们点击按钮后就会返回App_component__Fragment_div_button_onClick_Atxt02dBaJI这个事件方法的文件。

image.png

那么Qwik是如何修改变更的变量并把订阅的变量更新呢,然后同步渲染视图呢?答案其实也是跟solid的signal思路是一样的,都是通过proxy来监听,但是在useLexivcalScope中我们会得到序列化的json,里面会存有count变量,并定义了依赖集合subMap, 通过proxy代理count,一旦count写入变化,就会触发set并更新subMapp里面的依赖变量,然后更新视图。

所以Qwik项目一般主页会请求完整的html结构,和交互js。所以性能是要比nextjs等ssr框架是要更好的。

前端的未来——编译器

我们可以看到大量的框架在走向编译的阶段,而不是运行时。也就是我们用构建换运行时的时间,同时我们也在构建阶段做优化。这样我们完全可以使用rust、go等设计的编译器,带来更快的性能提升。比如之前的swc、rspack、esbuild。

Guess you like

Origin juejin.im/post/7253610755126427705
Recommended