张东升:您看我学React还有机会么

797 阅读5分钟

张东升是前端培训机构《六峰培训》的老师,靠着一手锋利的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开发版

大结局 你的选择

你回过神来,转过身,笑着对东升说......