-
Notifications
You must be signed in to change notification settings - Fork 1.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
面试官:说说React diff的原理是什么? #208
Comments
一会儿说只有删除创建,一会儿又说三种节点操作插入移动删除,可以移动了,有点没理解 |
层级和 component 只有删除创建。但是你遍历DOM树到了节点级,这时候就可以 删除、移动、创建 |
maxIndex 没说清楚什么意思 |
这是来自QQ邮箱的假期自动回复邮件。
您好,我最近正在休假中,无法亲自回复您的邮件。我将在假期结束后,尽快给您回复。
|
讲的很粗,没必要看 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
一、是什么
跟
Vue
一致,React
通过引入Virtual DOM
的概念,极大地避免无效的Dom
操作,使我们的页面的构建效率提到了极大的提升而
diff
算法就是更高效地通过对比新旧Virtual DOM
来找出真正的Dom
变化之处传统diff算法通过循环递归对节点进行依次对比,效率低下,算法复杂度达到 O(n^3),
react
将算法进行一个优化,复杂度姜维O(n)
,两者效率差距如下图:二、原理
react
中diff
算法主要遵循三个层级的策略:tree层级
conponent 层级
element 层级
tree层级
DOM
节点跨层级的操作不做优化,只会对相同层级的节点进行比较只有删除、创建操作,没有移动操作,如下图:
react
发现新树中,R节点下没有了A,那么直接删除A,在D节点下创建A以及下属节点上述操作中,只有删除和创建操作
conponent层级
如果是同一个类的组件,则会继续往下
diff
运算,如果不是一个类的组件,那么直接删除这个组件下的所有子节点,创建新的当
component D
换成了component G
后,即使两者的结构非常类似,也会将D
删除再重新创建G
element层级
对于比较同一层级的节点们,每个节点在对应的层级用唯一的
key
作为标识提供了 3 种节点操作,分别为
INSERT_MARKUP
(插入)、MOVE_EXISTING
(移动)和REMOVE_NODE
(删除)如下场景:
通过
key
可以准确地发现新旧集合中的节点都是相同的节点,因此无需进行节点删除和创建,只需要将旧集合中节点的位置进行移动,更新为新集合中节点的位置流程如下表:
如果当前节点在新集合中的位置比老集合中的位置靠前的话,是不会影响后续节点操作的,这里这时候被动字节不用动
操作过程中只比较oldIndex和maxIndex,规则如下:
diff
过程如下:当ABCD节点比较完成后,
diff
过程还没完,还会整体遍历老集合中节点,看有没有没用到的节点,有的话,就删除三、注意事项
对于简单列表渲染而言,不使用
key
比使用key
的性能,例如:将一个[1,2,3,4,5],渲染成如下的样子:
后续更改成[1,3,2,5,4],使用
key
与不使用key
作用如下:如果我们对这个集合进行增删的操作改成[1,3,2,5,6]
由于
dom
节点的移动操作开销是比较昂贵的,没有key
的情况下要比有key
的性能更好参考文献
https://zhuanlan.zhihu.com/p/140489744
https://zhuanlan.zhihu.com/p/20346379
The text was updated successfully, but these errors were encountered: