Signal ledger / designed reading stage
React 优先级控制:Lane
React 异步渲染中的优先级
Transition band / reading fieldLong-form note2021-08-15
Continue through the ledger
React 异步渲染中的优先级
React 早期的实现中使用了 expirationTime 用作标记优先级,后来切换到了
lane,开发者在pull request中解释了相关的差别。
同时,也有开发者对 React 团队没解释清楚的地方发起了提问。
在例子中可以看出 lane 作为处理优先级的架构优势
lane 直译为“赛道”,给任务部署在不同的赛道则拥有了不同的优先级。
在 ReactFiberLane 中定义了基于二进制的多个优先级变量,以及基于这些优先级变量的多个方法。
在触发更新的几种方法的源码里,可以看到获取 lane 都是通过
requestUpdateLane(fiber) 获得本次更新的 lane。
export function requestUpdateLane(fiber: Fiber): Lane {
const mode = fiber.mode;
if ((mode & ConcurrentMode) === NoMode) {
return (SyncLane: Lane);
}
const isTransition = requestCurrentTransition() !== NoTransition;
if (isTransition) {
if (currentEventTransitionLane === NoLane) {
currentEventTransitionLane = claimNextTransitionLane();
}
return currentEventTransitionLane;
}
const updateLane: Lane = (getCurrentUpdatePriority(): any);
if (updateLane !== NoLane) {
return updateLane;
}
// 根据不同的环境 对不同事件定义了不同的优先级,如 浏览器环境在 react-dom/src/events/ReactDOMEventListener.js 定义了 click 等事件的优先级
const eventLane: Lane = (getCurrentEventPriority(): any);
return eventLane;
}
在获取到 lane 后,会给本次创建的 update标记上该
lane,这样就对不同情况下创建的 update 标记了不同的优先级。
在接下来通过 scheduleUpdateOnFiber 方法调用 Scheduler
进入由调度器控制的调度工作。
在更新过程中有两种 lane,一种是创建 update 时的优先级,被标记在 fiber 上,另一种称为
renderLanes ,通过 getNextLanes 方法返回当前渲染会处理的最高优先级的更新 lane。
当 renderLanes 包括 updateLane 则认为该 update 在本次更新中满足优先级应该被处理。