这一次,彻底搞懂React的diff算法_51CTO博客_vue diff算法

blog.51cto.com · · 432 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

在前端面试中,只要涉及到React框架,diff算法便是我们绕不开的话题,这次让我们来系统性的梳理diff算法,不再被这个知识点所困扰。

什么是diff算法?

在了解diff算法之前,我们要直到diff算法并非React独家首创,但是React针对diff算法做了自己的优化,使得diff算法可以帮助我们计算出Virtual Dom中真正变化的部分,并只针对该部分进行实际的DOM操作,而非渲染整个页面,从而保证了每次操作后页面的高效渲染。

传统diff算法

要想了解React的diff算法,我们首先要知道传统的diff算法是如何设计并实现的。

传统diff算法的时间复杂度

传统diff算法的时间复杂度是O(N^3),其中N是树中节点的总数,这样的时间复杂度意味着如果要展示1000个节点,就要执行多达十亿次的比较,这种指数型的性能消耗对于前段渲染场景来说代价太高了。

React只有将diff算法进行改进,才有可能满足前端渲染所要求的的性能。

之所以传统diff算法的时间复杂度是O(N3)是因为两个二叉树的每一个节点进行两两对比的时间复杂度是O(N2),此时如果继续进行树的编辑操作(修改、删除)等还需要O(N)的时间复杂度,所以总的时间复杂度是O(N^3)。

React优化后的diff算法

React通过自己的优化,将O(N^3)的时间复杂度降到了O(N)。

React diff的三个前提策略

  1. Web UI中DOM节点跨层级的移动操作特别少,可以忽略不计。
  2. 拥有相同类的两个组件将会生成相似的树形结构,拥有不同类的两个组件将会生成不同的树形结构。
  3. 对于同一层级的一组子节点,它们可以通过唯一id进行区分。

React进行tree diff、component diff和element diff进行算法优化是基于上面三个前提策略。事实证明上面的三个前提策略是非常有效的。

核心策略1:tree diff(树策略)

对树进行分层比较,两棵树只会对同一层次的节点进行比较。

核心策略2:component diff(组件策略)

React是基于组件构建应用的,对于组件间的比较采用下面的方式:

  • 如果是同一类型的组件,按照原策略继续比较虚拟DOM树,对于同一类型的组件,有可能其虚拟DOM树并没有任何变化,如果能够在比较之前准确的知道这一点,可以节省大量的运算时间,所以React向用户提供了shouldComponentUpdate()来判断该组件是否需要进行diff。

  • 如果不是同一类型的组件,则将该组件判断为dirty component,从而替换掉整个组件下面的所有子节点。

核心策略3:element diff(元素策略)

对于同一层级的一组子节点,通过唯一id进行区分。

本文来自:blog.51cto.com

感谢作者:blog.51cto.com

查看原文:这一次,彻底搞懂React的diff算法_51CTO博客_vue diff算法

432 次点击  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传