Vue3 源码解析(三):静态提升

什么是静态提升

Vue3 尚未发布正式版本前,尤大在一次关于 Vue3 的分享中提及了静态提升,当时笔者就对这个亮点产生了好奇,所以在源码阅读时,静态提升也是笔者的一个重点阅读点。

那么什么是静态提升呢?当 Vue 的编译器在编译过程中,发现了一些不会变的节点或者属性,就会给这些节点打上标记。然后编译器在生成代码字符串的过程中,会发现这些静态的节点,并提升它们,将他们序列化成字符串,以此减少编译及渲染成本。有时可以跳过一整棵树。

<div>
  <span class="foo">
    Static
  </span>
  <span>
    {
    
    { dynamic }}
  </span>
</div>

例如这段模板代码,毫无疑问,我们能看出来 <span class="foo"> 这个节点,不论 dynamic 表达式如何变,它都不会再改变了。对于这样的节点,就可以打上标记进行静态提升。

而 Vue3 也可以对 props 属性进行静态提升。

<div id="foo" class="bar">
    {
    
    { text }}
</div>

例如这段模板代码,Vue3 会跳过节点,仅仅将将不再会变动的 id="foo"class="bar" 进行提升。

编译后的代码字符串

上面的例子我们只是简单的分析了一些模板,现在我们通过一个例子,来了解静态提升前后的变化。

<div>
  <div>
    <span class="foo"></span>
    <span class="foo"></span>
    <span class="foo"></span>
    <span class="foo"></span>
    <span class="foo"></span>
  </div>
</div>

来看这样一个模板,符合静态提升的条件,但是如果没有静态提升的机制,它会被编译成如下代码:

const { createVNode: _createVNode, openBlock: _openBlock, createBlock: _createBlock } = Vue

return function render(_ctx, _cache) {
  return (_openBlock(), _createBlock("div", null, [
    _createVNode("div", null, [
      _createVNode("span", { class: "foo" }),
      _createVNode("span", { class: "foo" }),
      _createVNode("span", { class: "foo" }),
      _createVNode("span", { class: "foo" }),
      _createVNode("span", { class: "foo" })
    ])
  ]))
}

编译后生成的 render 函数很清晰,是一个柯里化的函数,返回一个函数,创建一个根节点的 div,children 里有再创建一个 div 元素,最后在最里面的 div 节点里创建五个 span 子元素。

如果进行静态提升,那么它会被编译成这样:

const { createVNode: _createVNode, createStaticVNode: _createStaticVNode, openBlock: _openBlock, createBlock: _createBlock } = Vue

const _hoisted_1 = /*#__PURE__*/_createStaticVNode("<div><span class=\"foo\"></span><span class=\"foo\"><
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值