何为 Fiber:异步实现不同优先级任务的协调执行
对于 React 来说,Fiber 可以从两个角度理解:
1.协程
把渲染更新过程拆分成多个子任务,每次只做一小部分,做完看是否还有剩余时间,如果有继续下一个任务;如果没有,挂起当前任务,将时间控制权交给主线程,等主线程不忙的时候在继续执行。 这种策略叫做 Cooperative Scheduling(合作式调度),操作系统常用任务调度策略之一。
协程(Coroutines)是一种比线程更加轻量级的存在,正如一个进程可以拥有多个线程一样,一个线程可以拥有多个协程。
协程不是进程也不是线程,而是一个特殊的函数,这个函数可以在某个地方挂起,并且可以重新在挂起处外继续运行。所以说,协程与进程、线程相比并不是一个维度的概念。
- 一个线程内的多个协程虽然可以切换,但是多个协程是串行执行的,只能在一个线程内运行,没法利用CPU多核能力。
- 协程与进程一样,切换是存在上下文切换问题的。
举例:ES6 新增的Generator
2.一种数据结构
React将它视作一个执行单元,每次执行完一个’执行单元’, React 就会检查现在还剩多少时间,如果没有时间就将控制权让出去.
React 没有使用 Generator 这语法层面的让出机制,而是实现了自己的调度让出机制。这个机制就是基于’Fiber‘这个执行单元的。
Fiber的作用
目前市面上的主流前端框架/库 主要在以下两个方面实现性能优化:
1.在一个时间片里尽量做更多事,快速响应用户,让用户觉得够快(react)
2.优化每个任务,让任务执行的时间更短(vue)
空闲期(Idle Period)
通常,客户端线程执行任务时会以帧的形式划分,大部分设备控制在30-60帧是不会影响用户体验;在两个执行帧之间,主线程通常会有一小段空闲时间,requestIdleCallback可以在这个空闲期(Idle Period)调用空闲期回调(Idle Callback),执行一些任务。
Fiber与requestIdleCallback
Fiber所做的就是需要分解渲染任务,然后根据优先级使用API调度,异步执行指定任务:
- 低优先级任务由requestIdleCallback处理;
- 高优先级任务,如动画相关的由requestAnimationFrame处理;
- requestIdleCallback可以在多个空闲期调用空闲期回调,执行任务;
- requestIdleCallback方法提供deadline,即任务执行限制时间,以切分任务,避免长时间执行,阻塞UI渲染而导致掉帧;
假设用户调用 setState 更新组件, 这个待更新的任务会先放入队列中, 然后通过 requestIdleCallback 请求浏览器调度:
updateQueue.push(updateTask);
requestIdleCallback(performWork, {
timeout}