跳至主要內容

Diff算法

yyshino大约 3 分钟FrontEndVue

Diff算法

【diff算法的理解】

diff算法用来计算出Virtual DOM中改变的部分,然后针对该部分进行DOM操作,而不用重新渲染整个页面,渲染整个DOM结构的过程中开销是很大的,需要浏览器对DOM结构进行重绘与回流,而diff算法能够使得操作过程中只更新修改的那部分DOM结构而不更新整个DOM,这样能够最小化操作DOM结构,能够最大程度上减少浏览器重绘与回流的规模。

【原理】

diff算法:当数据发生改变时,set方法让调用Dep.notify通知所有订阅者Watcher数据发生更新,订阅者就会调用patch进行比较,然后将相应的部分渲染到真实DOM结构。

虚拟DOM:diff算法的基础是Virtual DOM,Virtual DOM是一棵以JavaScript对象作为基础的树,每一个节点称为VNode,用对象属性来描述节点,实际上它是一层对真实DOM的抽象,最终可以通过渲染操作使这棵树映射到真实环境上,简单来说Virtual DOM就是一个Js对象,用以描述整个文档。 在浏览器中构建页面时需要使用DOM节点描述整个文档。

【修改原则】

vue优化优化时间复杂度O(n)是通过一定策略进行的,React中提到了两个假设,在Vue中同样适用:

  • 两个不同类型的元素将产生不同的树。
  • 通过渲染器附带key属性,开发者可以示意哪些子元素可能是稳定的。

通俗点说就是:

  • 只进行统一层级的比较,如果跨层级的移动则视为创建和删除操作。
  • 如果是不同类型的元素,则认为是创建了新的元素,而不会递归比较他们的孩子。
  • 如果是列表元素等比较相似的内容,可以通过key来唯一确定是移动还是创建或删除操作。

比较后会出现几种情况,然后进行相应的操作:

  • 此节点被添加或移除->添加或移除新的节点。
  • 属性被改变->旧属性改为新属性。
  • 文本内容被改变->旧内容改为新内容。
  • 节点tag或key是否改变->改变则移除后创建新元素。