Vue3 模板引擎与编译的极致优化

88 阅读2分钟

vue 的模板语法来自于 mustache 胡子模板引擎,其原理是对 AST 树的分词逻辑
vue3 的编译器(devDependencies.@vue/compiler-sfc)会对 vue 文件进行编译,并直接运行在开发服务器上(dev 环境下),而 vue2 是先打包再运行。

image.png

1. 静态提升

vue3 的编译器通过打标记的方式,给所有节点分了静态节点动态节点的概念,vue2 则没有。

在编译器编译时,被提升的静态节点:

  • 元素节点:如 <h1>Talia</h1>

  • 没有绑定动态内容的属性,如 <div class="talia"></div>

被提升后,render 函数不再处理静态节点,从而提升 render 效率。

image.png

2. 预字符串化

不论是静态还是动态内容,vue2 是全部编译为了虚拟节点。

而 vue3 当编译器遇到大量连续的静态内容,会直接将其编译为一个普通字符串节点,从而大大降低虚拟节点的数量,提升效率。

3. 缓存处理函数

在编译的时候,先把事件的处理函数缓存起来,在运行 render 函数的时候,通过 _cache 参数来匹配该处理函数,保证了事件处理函数只生成一次,从而提升效率。

4. Block Tree

vue2 在对比新旧两棵树的时候(patch 过程),并不知道哪些静态哪些动态,只能一层层对比。

vue3 以 Block 作为根节点,只对比动态节点。当遇到不稳定的分支时,会又生成一个 Block 节点去对比动态节点。

5. PatchFlag

对单个节点进行比对时,vue2 并不知道这个节点的哪些信息会发生变化,所以比对的是全部信息(元素类型、属性、内容),而 vue3 通过 patchFlag 标记值的区分,来达到只对比变化的信息。

image.png

总结:以上 5 点,使客户端渲染提升了2倍,SSR(服务端渲染)提升了3倍,且项目中静态内容越多提升效果越明显。