into-piece / Step-By-Step

每天一题向前端架构师前进
4 stars 1 forks source link

fiber #13

Open into-piece opened 5 years ago

into-piece commented 5 years ago

react现状:一直以来react的动画卡顿都为人诟病,因js单线程,在执行逻辑,进行大型组件渲染的时候会占用浏览器主线程造成堵塞,这时候css dom树构建与用户输入等优先级比较高的任务都将被延迟搁置。 在现有React中,更新过程是同步的,因为JavaScript单线程的特点,每个同步任务不能耗时太长,不然就会让程序不会对其他输入作出相应,React的更新过程就是犯了这个禁忌,而React Fiber就是要改变现状。

React Fiber是对核心算法的一次重新实现

核心目标:扩大其适用性,包括动画,布局和手势。分为5个具体目标(后2个算送的):

二. 关键特性

Fiber的关键特性如下:

  1. 增量渲染(把渲染任务拆分成块,匀到多帧)
  2. 更新时能够暂停,终止,复用渲染任务
  3. 给不同类型的更新赋予优先级
  4. 并发方面新的基础能力

把任务切片,运行完一段便将控制权交还到react负责任务调度的模块,再根据任务的优先级,继续运行后面的任务。所以会导致某些组件渲染到一半便会打断运行其他紧急,优先级更高的任务,运行完却不会继续之前终端的部分,而是重新开始,所以会出现生命周期多次调用的情况。

四. Fiber reconciler

reconcile过程分为2个阶段(phase):

  1. (可中断)render/reconciliation 通过构造workInProgress tree得出change
  2. (不可中断)commit 应用这些DOM change

在第一阶段Reconciliation Phase,React Fiber会找出需要更新哪些DOM,这个阶段是可以被打断的;但是到了第二阶段Commit Phase,那就一鼓作气把DOM更新完,绝不会被打断。

比如说,一个低优先级的任务A正在执行,已经调用了某个组件的componentWillUpdate函数,接下来发现自己的时间分片已经用完了,于是冒出水面,看看有没有紧急任务,哎呀,真的有一个紧急任务B,接下来React Fiber就会去执行这个紧急任务B,任务A虽然进行了一半,但是没办法,只能完全放弃,等到任务B全搞定之后,任务A重头来一遍,注意,是重头来一遍,不是从刚才中段的部分开始,也就是说,componentWillUpdate函数会被再调用一次。

如何做到优先级划分的

requestIdleCallback && requestAnimationFrame

requestIdleCallback: 在线程空闲时期调度执行低优先级函数(可能会隔几帧) requestAnimationFrame: 在下一个动画帧调度前执行高优先级函数;