张东升是前端培训机构《六峰培训》的老师,靠着一手锋利的jQuery远近闻名。

第一集 失业
曾几何时,经过他们机构的培训,很多学员一毕业就靠三年前端经验拿到1w+的工资。那时候,真是前端的黄金时代。
甚至很多家长不辞辛苦将初中毕业的子女送来培训,美其名曰:让娃娃赢在内卷的路上。

面对失望的老婆,面对不给好脸色的亲戚,东升开始了艰难的求职。

第二集 就业
最终,东升来到了你所在的公司。公司的技术栈是React全家桶,技术总监老陈让你好好带带东升。
这一天,东升做的瀑布流组件在线上运行时出现严重性能问题。作为东升的导师,你也受到了严厉批评。这让你很火大。
在瀑布流向上划到顶时,顶部会出现“加载中”图标。在瀑布流向下划到底时,底部会出现“加载中”图标。
类似这样:
上划:
加载中
item0
item1
item2
item3
下划:
item0
item1
item2
item3
加载中
当从下划变为上划时,整个瀑布流列表都刷新了。
item0 加载中
item1 item0
item2 ===> item1
item3 item2
加载中 item3
明明在更新过程中,只有“加载中”位置变化,为什么其他组件会刷新呢?不是说有Diff算法么?

第三集 React好难
原来,在React内部Diff多个节点时,会经历两轮循环。
在第一轮循环中会寻找更新前后位置不变,type不变,key不变的节点。这些节点可以直接更新。
比如:
// 更新前
abcd
// 更新后
a(className="a")bdc
在这轮循环中a b满足条件(其中a更新className prop)。c d相对位置改变,不符合循环条件,所以c d在这轮循环未处理。
在下一轮循环中,React会处理剩下的节点。
- 更新前
有而更新后没有的节点会被标记删除 - 更新前
没有而更新后有的节点会被标记插入 - 顺序改变的节点会被
调整顺序。
其中插入和调整顺序,React最终都会调用parentNode.appendChild方法。
所以被执行插入和调整顺序的节点会成为一众兄弟节点中最后一个。
那么调整顺序的依据是什么呢?
React会比较当前需要调整顺序的节点与最后一个执行调整顺序的节点在更新前的相对位置。
- 如果
当前需要调整顺序的节点在更新前已经在最后一个执行调整顺序的节点后面,那么不需要处理。同时将最后一个执行调整顺序的节点的值更新为当前需要调整顺序的节点 - 如果
当前需要调整顺序的节点在更新前在最后一个执行调整顺序的节点前面,则需要调整当前需要调整顺序的节点的位置。在执行完parentNode.appendChild后他会成为最后一个兄弟节点
举例来说:
// 更新前
abcd
// 更新后
acdb
最后一个执行调整顺序的节点默认为第一项a。
c在更新前的同一位置为b,需要调整顺序。其中c更新前的位置在最后一个执行调整顺序的节点a的后面,则不需要处理。
同时最后一个执行调整顺序的节点变为c。
接着往下。d在更新前的同一位置为c,需要调整顺序。其中d更新前的位置在最后一个执行调整顺序的节点c的后面,则不需要处理。
同时最后一个执行调整顺序的节点变为d。
接着往下。b在更新前的同一位置为d,需要调整顺序。其中b更新前的位置在最后一个执行调整顺序的节点d的前面,需要调整顺序。
所以最终b被执行parentNode.appendChild变为最后一个兄弟节点,Diff算法完成。
这时候再回头来看东升的代码:
item0 加载中
item1 item0
item2 ===> item1
item3 item2
加载中 item3
你会发现,虽然肉眼可见的是只有加载中位置调整。但在React看来:
最后一个执行调整顺序的节点默认为第一项item0。
加载中在更新前的同一位置为item0,需要调整顺序。其中加载中 更新前的位置在最后一个执行调整顺序的节点 item0的后面,则不需要处理。
同时最后一个执行调整顺序的节点变为加载中。
加载中在更新前是最后一个节点,这意味着接下来的每个节点在更新前都在最后一个执行调整顺序的节点 加载中前面。都需要调整顺序!
最终的结果是:除了加载中,其他所有节点会依次执行parentNode.appendChild被插入到最后。难怪会有性能问题!
可惜,这些知识,对于只会简单使用React来说是不知道的。
第四集 爬山
东升在被你劈头盖脸一通吐槽后微微一笑,“这周太辛苦,要不周末一起去爬个山吧。”
想想自己也很久没运动,你,同意了。
在六峰山顶,你正在远眺这大好河山,东升在你身后悠悠的对你说:

React要完全学懂,必须明白源码的运行机制。你刚要冷冷的回绝他,突然想到:
有一本开源源码书,从理念到源码,包教包会。
这就是React技术揭秘
免费么?开源的,只求一个star。Github地址
本书的宗旨是打造一本严谨、易懂的React源码分析教程。 为了达到这个目标,在行文上,本书会遵循:
不预设观点 —— 所有观点来自React核心团队成员在公开场合发表的内容。
丰富的辅助资料 —— 包括在线Demo、文章视频。
代码剪枝 —— 讲解流程时只关注流程相关的代码,省略额外功能的干扰。
保持更新 —— 在React版本更新后会及时补充。当前版本v16.13.1开发版
大结局 你的选择
你回过神来,转过身,笑着对东升说......