vue3.0 beta 编译优化研究

尤雨溪 - 聊聊 Vue.js 3.0 Beta 官方直播完整版 2020-04-21里我发现了一个有意思的工具,输入模板展示它编译优化的结果,网址在这里:https://vue-next-template-explorer.netlify.app/

留意图片中,注意动态的 /* Text */ 的注释。识别 _openblock 后,vue 直接会找到带动态属性的节点(是AST里面会有标识声明),并且它标明了 /* Text */ 所以 diff 时会直接比对它的文本属性,节省了很大一笔 diff 遍历的次数。

<div>
  <span>hello</span>
  <span>hello</span>
  <span :id="test" :class="clazz">{{msg}}</span>
  <span>hello</span>
  <span>hello</span>
  <span>hello</span>
  <span>hello</span>
</div>
import { createVNode as _createVNode, toDisplayString as _toDisplayString, openBlock as _openBlock, createBlock as _createBlock } from "vue"

export function render(_ctx, _cache) {
  return (_openBlock(), _createBlock("div", null, [
    _createVNode("span", null, "hello"),
    _createVNode("span", null, "hello"),
    _createVNode("span", {
      id: _ctx.test,
      class: _ctx.clazz
    }, _toDisplayString(_ctx.msg), 11 /* TEXT, CLASS, PROPS */, ["id"]),
    _createVNode("span", null, "hello"),
    _createVNode("span", null, "hello"),
    _createVNode("span", null, "hello"),
    _createVNode("span", null, "hello")
  ]))
}

// Check the console for the AST

能识别出第三个 span 是动态的,并且还会标识它的哪些属性是动态的,其中 {{msg}} 是 TEXT,:class 是 CLASS,:id 是 PROPS

JSX 比起模板它的表达更加灵活,但因为它过于灵活,就无法做到下面的优化:

import { createVNode as _createVNode, toDisplayString as _toDisplayString, openBlock as _openBlock, createBlock as _createBlock } from "vue"

const _hoisted_1 = _createVNode("span", null, "hello", -1 /* HOISTED */)
const _hoisted_2 = _createVNode("span", null, "hello", -1 /* HOISTED */)
const _hoisted_3 = _createVNode("span", null, "hello", -1 /* HOISTED */)
const _hoisted_4 = _createVNode("span", null, "hello", -1 /* HOISTED */)
const _hoisted_5 = _createVNode("span", null, "hello", -1 /* HOISTED */)
const _hoisted_6 = _createVNode("span", null, "hello", -1 /* HOISTED */)

export function render(_ctx, _cache) {
  return (_openBlock(), _createBlock("div", null, [
    _hoisted_1,
    _hoisted_2,
    _createVNode("span", {
      id: _ctx.test,
      class: _ctx.clazz
    }, _toDisplayString(_ctx.msg), 11 /* TEXT, CLASS, PROPS */, ["id"]),
    _hoisted_3,
    _hoisted_4,
    _hoisted_5,
    _hoisted_6
  ]))
}

// Check the console for the AST

直接把静态节点抽离出去了,他只会编译阶段创建一遍,之后直接复用对象,不需要再创建了。还有一些其他的优化,比如说可以 cache 绑定的 click 函数,SSR 渲染直接变字符串输出。

composition api

详细介绍: https://composition-api.vuejs.org

posted @ 2020-05-08 22:14  Ever-Lose  阅读(926)  评论(0编辑  收藏  举报