返回

Vue3 中 compile 和 runtime 结合的 patch 过程

前端

好的,请稍等,我现在开始生成文章。

在上一篇文章中,我们分析了在编译过程静态节点的提升。并且,在文章的结尾也说了,下一篇文章将会介绍 patch 过程。说到「Vue3」的 patch 过程,其中最为津津乐道的就是靶向更新。靶向更新,顾名思义,即更新的过程是带有目标性的、直接性的。而,这也是和静态节点提升一样,是「Vue3」的 compile 和 runtime 结合,能够将前端的开发效率提升到极致。

compile 和 runtime 相结合的 patch 过程本质上就是将编译好的 AST 语法树通过 runtime 来执行。这一结合过程使我们无需关心底层实现,而是专注于我们最关心的数据更新。它使 patch 过程的灵活性大幅提升,其核心原理就是将 patch 过程分为两部分:标记过程与执行过程。

标记过程

标记过程实质上就是对 AST 语法树中需要更新的节点打标记。在 compile 阶段,编译器会将模板编译成 AST 语法树,在 AST 语法树中,会标记出需要更新的节点,这些节点就是需要被 patch 的节点。比如,在 following code 中:

<div id="app">
  <p>{{ message }}</p>
</div>

在编译过程中,编译器会将该模板编译成如下 AST 语法树:

{
  type: "div",
  props: [],
  children: [
    {
      type: "p",
      props: [],
      children: [
        {
          type: "text",
          content: "{{ message }}"
        }
      ]
    }
  ]
}

在 AST 语法树中,"{{ message }}" 这个节点就被标记为需要更新的节点。

执行过程

执行过程就是将标记过程标记出来的节点进行更新。在 runtime 阶段,执行器会根据 AST 语法树中的标记,依次执行更新操作。比如,在 following code 中:

vm.message = 'hello world'

执行器就会根据 AST 语法树中的标记,找到 "{{ message }}" 这个节点,然后将 "hello world" 赋值给 "{{ message }}" 这个节点。

靶向更新

靶向更新是「Vue3」中 patch 过程的一个非常重要的优化。在「Vue2」中,当数据发生更新时,会触发整个组件的重新渲染,这可能会导致大量的性能浪费。而在「Vue3」中,靶向更新只会在需要更新的节点进行更新,这大大减少了性能消耗。

靶向更新是通过标记过程和执行过程来实现的。在标记过程中,编译器会将需要更新的节点标记出来。在执行过程中,执行器会根据标记,只对需要更新的节点进行更新。

靶向更新不仅可以提高性能,还可以减少内存消耗。在「Vue2」中,当数据发生更新时,整个组件都会被重新创建,这可能会导致大量内存消耗。而在「Vue3」中,靶向更新只会在需要更新的节点进行更新,这可以减少内存消耗。

总结

compile 和 runtime 相结合的 patch 过程是「Vue3」中的一项重要优化。它将 patch 过程分为两部分:标记过程与执行过程,这使 patch 过程的灵活性大幅提升。同时,靶向更新的优化也大大提高了性能和减少了内存消耗。