React Fiber 初探

React16之前在做reconciler时,都是同步的,假设我们有一个如下的React tree。


假设节点1先执行setState(), 然后节点2执行setState(), 如果节点2对一个的是一个简单的Input, 其onChange=((e) => { this.setState({ value: e.target.value()})}),

由于1先setState,React会做1子树的reconciler,这个过程是同步的,如果1的子树特别大,这个过程可能会耗时很久,执行时间有可能超过16ms, 这时候节点2的setState迟迟不会执行,将导致用户输入无响应。

fiber就是为了解决这个问题,他将每个reconciler拆成很多个子任务,可以这么简单的理解,每个React Element都对应一个子任务,每个子任务的内容包含如下内容

1. 执行getStateDerivedFromProps

2. 执行shouldComponentUpdate

3. 执行render

4. 跟上一个版本进行compare, 生成对应的effects

每个react Element 对应的子任务可以称为unitwork, 当执行完一个节点的unitwork之后,如果还有空余时间,会继续执行下一个unitwork, 如果没有空余时间了,可以暂停,等待下一个周期的时候在接着执行下一个unitwork。

1对应的setState对应reconciler执行到一半(在requestIdleCallbalck里做),下个周期用户可能会下拉滚动条等操作,这时候浏览器先做UI layout,将滚动条滑倒对应位置,然后在这个周期的requestIdleCallbalck做剩余的reconciler

再看另一种情形,1对应的setState对应reconciler执行到一半时, 2的setState开始执行,由于其优先级比较高,1的setState会先暂停,先执行2的setState,当2的setState执行完时, 再回到1的setState, 此时估计1之前做的一半会都丢弃掉,重新在做一遍。所以getStateDerivedFromProps,shouldComponentUpdate,render生命周期可能在一次reconciler里会执行多次,这些生命周期不能包含任何side effects操作。


参考文献:

1. https://medium.com/dailyjs/the-how-and-why-on-reacts-usage-of-linked-list-in-fiber-67f1014d0eb7

2. https://medium.com/react-in-depth/inside-fiber-in-depth-overview-of-the-new-reconciliation-algorithm-in-react-e1c04700ef6e

2. https://github.com/acdlite/react-fiber-architecture

4. https://juejin.im/post/5ab7b3a2f265da2378403e57




©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容