React Lane 模型
Lane 是 React 中用于表示任务优先级的概念。优先级分为高优先级与低优先级。
调度流程概览
- 编写代码绑定事件时,根据不同的事件,React 会给它分配一个 lane。
- 触发该事件产生更新时,可以获取到这个事件的优先级,把产生的更新放到对应 Fiber 的更新队列中。
- 更新产生后,对应 Fiber 节点产生变化,开始新一轮调度。我们要自底向上更新优先级,通过合并 Fiber 的 lane 和父节点的 childLanes,这些更新最后会被收集到 Fiber root 的 pendingLanes 中,然后将事件的触发时间更新到 eventTimes 中。
- 任务调度开始时,先判断 pendingLanes 中有没有过期的任务。如果有任务过期,将它放到 expiredLanes 紧急队列中尽快调度防止饥饿;如果任务没设置过期时间,就根据它的 lane 设置过期时间(优先级越高过期越快)。
- 之后根据 expiredLanes、pendingLanes 以及 suspendedLanes 取得当前最紧急的任务,根据优先级判断当前最紧急的任务能否打断现有任务的执行(高优先级抢占),然后根据任务的优先级决定用什么模式开启任务。我们把计算得到的优先级最高的一批任务放到 subtreeRenderLanes 中,作为这次调度的执行任务。
- 进行一次 diff 操作,根据对应 Fiber 上的 lanes 是否在 subtreeRenderLanes 中判断能否直接复用。
- 如果不能复用,则调用 processUpdateQueue 处理 Fiber 上的更新队列,根据 fiber 上的 lanes 是否在 subtreeRenderLanes 中判断是否要执行此更新。如果一个任务更新了,就删除对应的 lane。
- diff 流程结束后,进入 commit 阶段:将每个节点和孩子节点的 lanes 合并,计算出还没有更新的 lanes 和已经更新的 lanes,从 root 中删除已经更新的 lanes,把未更新的 lanes 作为下一次调度的任务,然后开始新的调度,循环往复,直到所有任务运行完毕。
Lane 的种类
React 中有多种类型的 Lanes,每种 Lane 都有不同的优先级和用途:
- Sync:此 Lane 用于处理同步更新(用户在当前任务中触发的更新),具有最高的优先级,将会立即执行。
- Input:此 Lane 用于处理用户交互触发的更新,例如点击、滚动或输入。
- Animation:此 Lane 用于处理动画更新,例如 CSS 动画或第三方动画库的动画。
- Paint:此 Lane 用于处理需要重绘屏幕的更新,例如更改 DOM 元素的样式或文本。
- Passive:此 Lane 用于处理低优先级的更新,例如更新后台数据或执行计时器回调。
来源整理自:vue3js.cn 面试官系列



