先说浏览器的渲染模式

这里引用一段掘金作者“我是你的超级英雄”在深入剖析:Vue核心之虚拟DOM 一文中的描述:

所有的浏览器渲染引擎工作流程大致分为5步:创建DOM 树 —> 创建 Style Rules -> 构建 Render 树 —> 布局 Layout -—> 绘制 Painting。
第一步,构建 DOM 树:用 HTML 分析器,分析 HTML 元素,构建一棵 DOM 树;
第二步,生成样式表:用 CSS 分析器,分析 CSS 文件和元素上的 inline 样式,生成页面的样式表;
第三步,构建 Render 树:将 DOM 树和样式表关联起来,构建一棵 Render 树(Attachment)。每个 DOM 节点都有 attach 方法,接受样式信息,返回一个 render 对象(又名 renderer),这些 render 对象最终会被构建成一棵 Render 树;
第四步,确定节点坐标:根据 Render 树结构,为每个 Render 树上的节点确定一个在显示屏上出现的精确坐标;
第五步,绘制页面:根据 Render 树和节点显示坐标,然后调用每个节点的 paint 方法,将它们绘制出来。

DOM树是整个页面的骨架,承载着内容和结构的任务,而当下的Web开发会有大量与DOM树交互的需要,因此,虚拟DOM和diff算法应运而生,先在虚拟DOM上更新,再diff后应用局部的更新,减少了直接操作DOM树带来的重绘与重排问题,有关diff算法会在下一篇文章中做分析。

Patch是何时执行的?

当vnode和oldVnode都存在、oldVnode不是真实节点,并且vnode和oldVnode是同一节点时,才会调用patchVnode进行patch。

Patch/Update有哪些情况?

这里我们只说明后续响应的情况:

  • 如果节点不同,则根据 旧节点 参考使用 nextSibling 创建新节点并移除旧节点,其中Vue.js需要更新其中占位符节点(实际DOM节点);
  • 如果节点相同,则更新vnode的属性并更新到实际节点,旧节点本质上仍然不变;
  • 如果节点存在子元素且子元素发生改变,则通过 updateChildren 更新子节点,这里可能会用到我们的key属性,进行快速比对diff。