React Diff 会帮助咱们计算出 Virtual DOM 中真正发生变化的部分,而且只针对该部分进行实际的DOM操做,而不是对整个页面进行从新渲染html
传统的diff算法是使用循环递归对节点进行依次对比,复杂度为O(n^3),效率低下。react
React 经过使用 updateDepth 对 虚拟DOM树进行层次遍历算法
两棵树只对同一层级节点进行比较,只要该节点不存在了,那么该节点与其全部子节点会被彻底删除,不在进行进一步比较。性能
只须要遍历一次,便完成对整个DOM树的比较。优化
React diff 只考虑同层次的节点位置变换,若为跨层级的位置变化,则是建立节点和删除节点的操做。即在新位置上从新建立相同的节点,而删除原位置的节点。3d
Tips: React 官方建议不要进行DOM节点的跨层级操做,但是经过CSS来隐藏,显示节点,而不是真正地删除和添加DOM节点,保持稳定的DOM结构会对性能提高有帮助。code
shouldComponentUpdate()
方法来判断是否React官方文档对于 shouldComponentUpdate的介绍component
dirty component
,从而替换整个组件的全部节点。就算结构再类似的组件,只要 React 判断是不一样的组件,就不会判断是否为不一样类型的组件,就不会比较其结构,而是删除组件以及其子组件,并建立新的组件以及其子节点。orm
对于处于同一层级的节点,React diff 提供了三种节点操做: 插入,移动,删除cdn
按新集合中顺序开始遍历
lastIndex
就认为 B 对于集合中其余元素位置无影响,不进行移动,以后lastIndex
= max(index, lastIndex) = 1lastIndex
= 1, 知足 index < lastIndex
, 则对A进行移动操做,此时lastIndex
= max(Index, lastIndex) = 1lastIndex
=max(index, lastIndex) = 3lastIndex
= max(index, lastIndex) = 31.同上面那种情形,B不进行移动,lastIndex
=1
2.新集合中取得E,发现旧中不存在E,在 lastIndex
处建立E,lastIndex
++
3.在旧集合中取到C,C不移动,lastIndex
=2
4.在旧集合中取到A,A移动到新集合中的位置,lastIndex
=2
5.完成新集合中全部节点diff后,对旧集合进行循环遍历,寻找新集合中不存在但就集合中的节点(此例中为D),删除D节点。
此例中D直接从最后一位提高至第一位,致使lastIndex
在第一步直接提高为3,使ABC在进行index与lastIndex的判断时均处于 index < lastIndex 的状况,使ABC都须要作移动操做。因此咱们应该减小将最后一个节点提高至第一个的操做,若是操做频率较大或者节点数量较多时,会对渲染性能产生影响。
参考资料
《深刻React技术栈》