react调度的理解

925 阅读2分钟

1.为什么需要调度?

大家都知道 JS 和渲染引擎是一个互斥关系。如果 JS 在执行代码,那么渲染引擎工作就会被停止。假如我们有一个很复杂的复合组件需要重新渲染,那么调用栈可能会很长调用栈过长,再加上如果中间进行了复杂的操作,就可能导致长时间阻塞渲染引擎带来不好的用户体验,调度就是来解决这个问题的

2.react 调度的流程?

  • 首先每个任务都会有各自的优先级,通过当前时间加上优先级所对应的常量我们可以计算出 expriationTime高优先级的任务会打断低优先级任务
  • 在调度之前,判断当前任务是否过期,过期的话无须调度,直接调用 port.postMessage(undefined),这样就能在渲染后马上执行过期任务了
  • 如果任务没有过期,就通过 requestAnimationFrame 启动定时器,在重绘前调用回调方法
  • 在回调方法中我们首先需要计算每一帧的时间以及下一帧的时间,然后执行 port.postMessage(undefined)
  • channel.port1.onmessage 会在渲染后被调用,在这个过程中我们首先需要去判断当前时间是否小于下一帧时间。如果小于的话就代表我们尚有空余时间去执行任务;如果大于的话就代表当前帧已经没有空闲时间了,这时候我们需要去判断是否有任务过期,过期的话不管三七二十一还是得去执行这个任务。如果没有过期的话,那就只能把这个任务丢到下一帧看能不能执行了

参考出处:https://yuchengkai.cn/react/2019-06-04.html#%E6%96%87%E7%AB%A0%E7%9B%B8%E5%85%B3%E8%B5%84%E6%96%99

3.Fiber的实现原理?

旧版 React 通过递归的方式进行渲染,使用的是 JS 引擎自身的函数调用栈,它会一直执行到栈空为止。而Fiber实现了自己的组件调用栈,它以链表的形式遍历组件树,可以灵活的暂停、继续和丢弃执行的任务。实现方式是使用了浏览器的requestIdleCallback这一 API