Diff算法
大约 3 分钟
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是否改变->改变则移除后创建新元素。