解读Vue3模板编译优化

本文探讨Vue3模板编译与Vue2的区别,关注VDOM Diff算法的优化。介绍编译入口、主流程、PatchFlag计算及其在render优化中的作用,揭示Vue3如何通过PatchFlag提升性能。
摘要由CSDN通过智能技术生成

今天的文章打算学习下 Vue3 下的模板编译与 Vue2 下的差异,以及 VDOM 下 Diff 算法的优化。

编译入口

了解过 Vue3 的同学肯定知道 Vue3 引入了新的组合 Api,在组件 mount 阶段会调用 setup 方法,之后会判断 render 方法是否存在,如果不存在会调用 compile 方法将 template 转化为 render

// packages/runtime-core/src/renderer.ts
const mountComponent = (initialVNode, container) => {
   
  const instance = (
    initialVNode.component = createComponentInstance(
      // ...params
    )
  )
  // 调用 setup
  setupComponent(instance)
}

// packages/runtime-core/src/component.ts
let compile
export function registerRuntimeCompiler(_compile) {
   
  compile = _compile
}
export function setupComponent(instance) {
   
  const Component = instance.type
  const {
    setup } = Component
  if (setup) {
   
    // ...调用 setup
  }
  if (compile && Component.template && !Component.render) {
   
      // 如果没有 render 方法
    // 调用 compile 将 template 转为 render 方法
    Component.render = compile(Component.template, {
   ...})
  }
}

这部分都是 runtime-core 中的代码,之前的文章有讲过 Vue 分为完整版和 runtime 版本。如果使用 vue-loader 处理 .vue 文件,一般都会将 .vue 文件中的 template 直接处理成 render 方法。

//  需要编译器
Vue.createApp({
   
  template: '<div>{
   { hi }}</div>'
})

// 不需要
Vue.createApp({
   
  render() {
   
    return Vue.h('div', {
   }, this.hi)
  }
})

完整版与 runtime 版的差异就是,完整版会引入 compile 方法,如果是 vue-cli 生成的项目就会抹去这部分代码,将 compile 过程都放到打包的阶段,以此优化性能。runtime-dom 中提供了 registerRuntimeCompiler 方法用于注入 compile 方法。

主流程

在完整版的 index.js 中,调用了 registerRuntimeCompilercompile 进行注入,接下来我们看看注入的 compile 方法主要做了什么。

// packages/vue/src/index.ts
import {
    compile } from '@vue/compiler-dom'

// 编译缓存
const compileCache = Object.create(null)

// 注入 compile 方法
function compileToFunction(
    // 模板
  template: string | HTMLElement,  // 编译配置
  options?: CompilerOptions
): RenderFunction {
   
  if (!isString(template)) {
   
    // 如果 template 不是字符串
    // 则认为是一个 DOM 节点,获取 innerHTML
    if (template.nodeType) {
   
      template = template.innerHTML
    } else {
   
      return NOOP
    }
  }

  // 如果缓存中存在,直接从缓存中获取
  
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值