vue3编译器原理

223 阅读1分钟

Vue3编译器是什么

将用户编写的 模板template 转换为 渲染函数render

为什么需要编译器

  1. 前端程序员更加喜欢使用html格式去描述试图
  2. 声明式渲染
  3. 有利于性能优化

下面就是直接编写渲染的过程,很显然不方便用户编写代码

<script>
  const {createApp, h} = Vue
  createApp({    
    render() {
      return h(Vue.Fragment, [
        h('h1', 'vue 编译器'),
        h('p', this.counter * 2)
      ])
    }
  }).mount('#app')
</script>

Vue template 和 React JSX异同

  • 流程都是生产虚拟dom
    • vue
      • template => render => vnode
      • global版本运行时执行编译
    • react
      • jsx => create() => vdom
  • 执行时刻
    • vue
      • 打包时预编译template为render,不再拥有编译功能,不能使用template
      • global版本运行时执行编译,可以使用template
    • react
      • babel转译为js
  • 编译期间优化
    • vue3特有的编译期间优化
    • react是操作js,缺少上小文,优化难度,比vue难,vue可以在模板中分析出静态节点

vue3编译过程调试

template explorer 这个链接页面下 打开控制台可以看到ast输出

compile.ts 65行代码给baseCompile函数打上断点

<div id="app">
  <h1>vue3 编译器</h1>
  <p>{{counter}}</p>
</div>
<script src="../dist/vue.global.js"></script>
<script>
  const {createApp, h} = Vue
  const app = createApp({
    data() {
      return {
        counter: 1
      }
    },
  })
  app.mount('#app')
  // 输出渲染函数
  console.log(app._instance.render)
</script>

vue3编译优化策略

sfc.playground

  • 静态节点提升 - static hoisting 内存换时间
  • 补丁标记 - patchFlags 精确更新节点,不需要执行额外代码都可以跳过,而vue2是把没用的代码也要跑一边
  • 事件处理器缓存 - event handler cache 缓存绑定的事件
  • 区块 - block dynamicChildren是数组