前端技术

React 设计原理 2 前端框架的实现原理

2023-06-04  本文已影响0人  吴摩西

Svelte

react 原理-svelte.png

借由模板语法的约束,经过 AOT 的编译优化,Svelte 可以直接建立 “自变量与元素的对应关系”。Svelte 在运行时忽略了“根据自变量变化计算出 UI 变化”这一步骤,使其在执行“细粒度的更新”(比如更新大列表的某一行)时比“使用 VDOM 的框架” 的整体更新路径更短。

Vue3

Vue3 是一款组件级别的前端框架,这意味着它会建立“自变量与组件的对应关系”,并在此基础上通过 VDOM 寻找 “自变量变化到UI变化的关系”。同时,由于 Vue3 使用模板语法描述 UI,因此它可以从 AOT 中受益。 Vue3 原理如下:


react 原理 - Vue3.png

Vue3 的代码如下

<script setup>
import { ref } from 'vue'
let count = ref(0);
</script>
<template>
  <h1 @click="count ++">{{ count }}</h1>
</template>

Vue3 会对每个组件生成 watchEffect,在初始化和依赖的变量变化时,会执行
(1). 调用组件的 render 函数,生产 VNode,

// 模板代码
<h1 @click="count++">{{ count }}</h1>

//编译后生成的 render 函数
function render(_ctx, _cache, $props, $setup, $data, $options) {
  return (_openBlock(), _createElementBlock("h1", (
    onClick: _cache(0) || (_cache(0) = $event => (_ctx.count++))
  ), _toDisplayString(_ctx.count), 1 /* TEXT */));
}

effect 会订阅“其回调函数上下文中执行的所有自变量”,当自变量发生变化后,effect 会重新执行。所以当上述 render 函数执行后,内部的自变量变化 (_ctx.count 的变化) 会被该 effect 订阅。
(2) 在步骤 (1) 执行后,render 函数的返回值为本次更新的 VNode,它会与上一次更新的 VNode 同时传入 patch 方法,执行 VDOM 的相关操作,找到 “本次自变量变化导致的元素变化”,并最终执行对应的 DOM 操作。

React

作为应用级框架,React 的实现原理很简单,

react 过程.png
  1. 触发事件,改变自变量,开启更新流程;
  2. 执行 VDOM 相关操作,在 React 中被称为 reconcile;
  3. 根据步骤 2 计算出所需要变化的 UI, 执行对应的 UI 操作,在 React 中被称为 commit。

React 被称为应用级框架的原因在于,其每一次更新流程都是从应用的根结点开始的。对比与其他框架:

由于每次都是全更新,React 不关心是哪个自变量发生变化,也不需要 “细粒度更新” 和 AOT。一方面 React 内部有其优化机制,另一方面,React 暴露了一些 API 来减少无意义的遍历过程,比如 shouldComponentUpdateReact.memoPureComponent

Vue3 由于细粒度更新和 AOT 优化,已经减少了大部分无意义的遍历过程。可以说: 由于 React 没有完成这部分性能优化的任务,因此这部分工作交到了开发者手中

相对的,基于“重运行时”架构,React 拓展了许多令人耳目一新的能力,比如:

上一篇下一篇

猜你喜欢

热点阅读