拖拽式网站建设哪家专业网站建设建设多少钱
- 作者: 五速梦信息网
- 时间: 2026年04月20日 08:20
当前位置: 首页 > news >正文
拖拽式网站建设哪家专业,网站建设建设多少钱,上海商业连锁设计,微信群拉人的营销方法优先级{#lanes}
在全局变量中有不少变量都以Lanes命名 如workInProgressRootRenderLanes, subtreeRenderLanes其作用见上文注释它们都与优先级相关 React中有3套优先级体系#xff0c;并了解了它们之间的关联关系现在来看下fiber树构造过程中#xff0c;车道模型Lane的具体应…优先级{#lanes}
在全局变量中有不少变量都以Lanes命名 如workInProgressRootRenderLanes, subtreeRenderLanes其作用见上文注释它们都与优先级相关 React中有3套优先级体系并了解了它们之间的关联关系现在来看下fiber树构造过程中车道模型Lane的具体应用在整个react-reconciler包中Lane的应用可以分为3个方面
1 update优先级(update.lane){#update-lane} update对象它是一个环形链表. 对于单个update对象来讲update.lane代表它的优先级称之为update优先 观察其构造函数, 其优先级是由外界传入 export function createUpdate(eventTime: number, lane: Lane): Update* {const update: Update* {eventTime,lane,tag: UpdateState,payload: null,callback: null,next: null,}return update;
}在React体系中有2种情况会创建update对象 1.应用初始化在react-reconciler包中的updateContainer函数中 export function updateContainer(element: ReactNodelist,container: OpaqueRoot,parentComponent: ?React$Componentany, any,callback: ?Function,
):Lane {const current container.current;const eventTime requestEventTime();const lane requestUpdateLane(current); //根据当前时间创建一个update优先级const update createUpdate(eventTime, lane); //lane被用于创建update对象update.payload { element };enqueueUpdate(current, update);scheduleUpdateOnFiber(current, lane, eventTime);return lane;
}发起组件更新: 假设在 class 组件中调用 setState const classComponentUpdater {isMounted,enqueueSetState(inst, payload, callback) {const fiber getInstance(inst);const eventTime requestEventTime(); // 根据当前时间创建一个update优先级const lane requestUpdateLane(fiber); // lane被用于创建update对象const update createUpdate(eventTime, lane);update.payload payload;enqueueUpdate(fiber, update);scheduleUpdateOnFiber(fiber, lane, eventTime);},
};可以看到无论是应用初始化或者发起组件更新创建update.lane的逻辑都是一样的 都是根据当前时间创建一个update优先级 export function requestUpdateLane(fiber: Fiber): Lane {// Special casesconst mode fiber. mode;if ((mode BlockingMode) NoMode) {// legacy 模式return (SyncLane: Lane);} else if ((mode ConcurrentMode) NoMode) {// blocking 模式return getCurrentPrioritylevel() ImmediateSchedulerPriority? (Synclane: Lane): (SyncBatchedLane: Lane);}//concurrent模式if (currentEventWipLanes NoLanes) {currentEventWipLanes workInProgressRootIncludedLanes;}const isTransition requestCurrentTransition() ! NoTransition;if(isTransition) {// 特殊情况处于suspense过程中if (currentEventPendingLanes ! NoLanes) {currentEventPendingLanes mostRecentlyUpdatedRoot ! null? mostRecentlyUpdatedRoot. pendingLanes: NoLanes;}return findTransitionLane(currentEventWipLanes, currentEventPendingLanes);}// 正常情况获取调度优先级const schedulerPriority getCurrentPriorityLevel();let lane;if ((executionContext DiscreteEventContext) ! NoContext schedulerPriority UserBlockingSchedulerPriority){// executionContext 存在输入事件且调度优先级是用户阻塞性质lane findUpdateLane(InputDiscreteLanePriority, currentEventWipLanes);} else {// 调度优先级转换为车道模型const schedulerLanePriority schedulerPriorityToLanePriority(schedulerPriority,);lane findUpdateLane(schedulerLanePriority, currentEventWipLanes);}return lane;
}可以看到requestUpdateLane的作用是返回一个合适的update优先级. 1.legacy模返回SyncLane2.blocking模式返回SyncLane3.concurrent模式 正常情况下根据当前的调度优先级来生成一个1ane.特殊情况下处于suspense过程中会优先选择TransitionLanes通道中的空闲通道 如果所有TransitionLanes通道都被占用就取最高优先级 最后通过scheduleUpdateOnFiber(current, lane, eventTime);函数 把 update.lane正式带入到了输入阶段 scheduleUpdateOnFiber是输入阶段的必经函数此处以 update.lane 的视角分析 export function scheduleUpdateOnFiber(fiber: Fiber,lane:Lane,eventTime: number,
) {if(lane SyncLane) {// legacyblocking模式if ((executionContext LegacyUnbatchedContext) ! NoContext (executionContext (RenderContext CommitContext)) NoContext) {performSyncWorkOnRoot(root);} else {ensureRootIsScheduled(root,eventTime); // 注册回调任务if (executionContext NoContext) {flushSyncCallbackQueue(); // 取消schedule调度主动刷新回调队列}}} else {// concurrent模式ensureRootIsScheduled(root, eventTime);}
}当laneSyncLane也就是legacy或blocking模式中注册完回调任务之后 (ensureRootIsScheduled(root, eventTime)),如果执行上下文为空 会取消schedule调度主动刷新回调队列flushsyncCallbackQueue() 这里包含了一个热点问题(setState到底是同步还是异步)的标准答案 如果逻辑进入 flushSyncCallbackQueue(executionContext NoContext) 则会主动取消调度并刷新回调立即进入fiber树构造过程当执行setState下一行代码时fiber树已经重新渲染了故setState体现为同步 正常情况下不会取消schedule调度 由于schedule调度是通过MessageChannel触发宏任务故体现为异步
2 ) 渲染优先级(renderLanes) 这是一个全局概念每一次render之前首先要确定本次render的优先级具体对应到源码如下 //…省略无关代码
function performSyncWorkOnRoot(root) {let lanes;let exitStatus;//获取本次render的优先级lanes getNextLanes(root, lanes);exitStatus renderRootSync(root, lanes);
}
//…省略无关代码
function performConcurrentWorkOnRoot(root) {//获取本次render的优先级let lanes getNextLanes(root,root workInProgressRoot ? workInProgressRootRenderLanes : NoLanes,);if (lanes NoLanes){return null;}let exitStatus renderRootConcurrent(root, lanes);
}可以看到无论是 Legacy 还是 Concurrent 模式在正式 render 之前都会调用 getNextLanes 获取一个优先级 //…省略部分代码
export function getNextLanes(root: FiberRoot, wipLanes: Lanes): Lanes {// 1. check是否有等待中的lanesconst pendingLanes root.pendingLanes;if (pendinglanes NoLanes) {return_highestLanePriority NoLanePriority;return NoLanes;}let nextLanes NoLanes;let nextLanePriority NoLanePriority;const expiredLanes root.expiredLanes;const suspendedLanes root.suspendedLanes;const pingedLanes root.pingedLanes;// 2.check是否有已过期的Lanesif (expiredlanes ! NoLanes) {nextLanes expiredLanes;nextlanePriority return_highestLanePriority SynclanePriority;} else {const nonIdlePendingLanes pendingLanes NonIdleLanes;if (nonIdlePendingLanes ! NoLanes) {//非Idle任务…} else {//Idle任务…}}if (nextLanes NoLanes) {return NoLanes;}return nextLanes;
}getNextLanes 会根据 fiberRoot 对象上的属性(expiredLanes, suspendedLanes, pingedLanes等) 确定出当前最紧急的1anes 此处返回的lanes会作为全局渲染的优先级用于fiber树构造过程中 针对fiber对象或update对象只要它们的优先级如fiber.lanes和update.lane比渲染优先级低都将会被忽略
3 ) fiber优先级(fiber.lanes)
介绍过fiber对象的数据结构.其中有2个属性与优先级相关 1.fiber.lanes 代表本节点的优先级 2.fiber.childLanes 代表子节点的优先级从FiberNode的构造函数中可以看出fiber.lanes 和 fiber.childLanes的初始值都为NoLanes在fiber树构造过程中使用全局的渲染优先级 ( renderLanes)和 fiber.lanes 判断 fiber 节点是否更新. 如果全局的渲染优先级rendertanes不包括fiber.lanes证明该fiber节点没有更新可以复用.如果不能复用进入创建阶段 function beginWork(current: Fiber| null,workInProgress: Fiber,renderLanes: Lanes,
): Fiber | null {const updatelanes workInProgress.lanes;if(current ! null) {const oldProps current.memoizedProps;const newProps workInProgress.pendingProps;if(oldProps ! newProps ||hasLegacyContextChanged()// Force a re-render if the implementation changed due to hot reload:(_DEV__ ? workInProgress.type ! current. type : false)) {didReceiveUpdate true;} else if (!includesSomeLane(renderLanes, updateLanes)) {didReceiveUpdate false;//本fiber节点的没有更新可以复用进入bailout逻辑return bailoutOnAlreadyFinishedwork(current, workInProgress, renderlanes);}}// 不能复用创建新的fiber节点workInProgress.lanes NoLanes;//重优为 NoLanesswitch (workInProgress.tag) {case ClassComponent: {const Component workInProgress.type;const unresolvedProps workInProgress. pendingProps;const resolvedProps workInProgress.elementType Component? unresolvedProps: resolveDefaultProps(Component, unresolvedProps);return updateClassComponent(current,workInProgress,Component,resolvedProps,// 正常情况下渲染优先级会被用于fier树的构透过程renderLanes,);}}
}栈帧管理 在React源码中每一次执行fiber树构造 也就是调用performSyncWorkOnRoot或者performConcurrentWorkOnRoot函数的过程都需要一些全局变量来保存状态 如果从单个变量来看它们就是一个个的全局变量. 如果将这些全局变量组合起来它们代表了当前fiber树构造的活动记录 通过这一组全局变量可以还原fiber树构造过程 比如时间切片的实现过程fiber树构造过程被打断之后需要还原进度全靠这一组全局变量 所以每次fiber树构造是一个独立的过程需要独立的一组全局变量 在React内部把这一个独立的过程封装为一个栈帧stack 简单来说就是每次构造都需要独立的空间 所以在进行fiber树构造之前如果不需要恢复上一次构造进度都会刷新栈帧源码在prepareFreshStack函数 function renderRootConcurrent(root: FiberRoot, lanes: Lanes) {const prevExecutionContext executionContext;executionContext | RenderContext;const prevDispatcher pushDispatcher();// 如果fiberRoot变动或者update.lane变动都会刷新栈帧丢弃上一次渲染进度if (workInProgressRoot ! root || workInProgressRootRenderLanes ! lanes) {resetRenderTimer();// 刷新找帧prepareFreshStack(root, lanes);startWorkOnPendingInteractions(root, lanes);}
}// 刷新栈帧重置FiberRoot上的全局属性和fiber树构造循环过程中的全局变量
function prepareFreshStack(root: FiberRoot, lanes: Lanes) {// 重置FiberRoot对象上的属性root.finishedWork null;root.finishedLanes NoLanes;const timeoutHandle root.timeoutHandle;if(timeoutHandle ! noTimeout) {root.timeoutHandle noTimeout;cancelTimeout(timeoutHandle);}if (workInProgress ! null) {let interruptedWork workInProgress.return;while (interruptedWork ! null){unwindInterruptedWork(interruptedWork);interruptedWork interruptedWork.return;}}// 重置全局变量workInProgressRoot root;workInProgress createWorkInProgress(root.current, null); // 给HostRootFiber对象创建一个alternateworkInProgressRootRenderLanes subtreeRenderLanes workInProgressRootIncludedLanes laneworkInProgressRootExitStatus RootIncomplete;workInProgressRootFatalError null;workInProgressRootSkippedlanes NoLanes;
}注意其中的 createWorkInProgress(root.current, null) 其参数 root.current 即 HostRootFiber 作用是给 HostRootFiber 创建一个 alternate副本 workInProgress 指针指向这个副本, 即 workInProgress HostRootFiber.alternate 在前文 double buffering 中分析过HostRootFiber.alternate 是正在构造的fiber树的根节点
- 上一篇: 推销网站话术吴中区网站设计公司
- 下一篇: 拖拽式网站网页版qq为什么登录不了
相关文章
-
推销网站话术吴中区网站设计公司
推销网站话术吴中区网站设计公司
- 技术栈
- 2026年04月20日
-
推特登陆 网站建设西宁房地产网站建设
推特登陆 网站建设西宁房地产网站建设
- 技术栈
- 2026年04月20日
-
推特登陆 网站建设企业门户网站建设优势
推特登陆 网站建设企业门户网站建设优势
- 技术栈
- 2026年04月20日
-
拖拽式网站网页版qq为什么登录不了
拖拽式网站网页版qq为什么登录不了
- 技术栈
- 2026年04月20日
-
拖拽自助建站系统源码官方网站的网络营销功能分析
拖拽自助建站系统源码官方网站的网络营销功能分析
- 技术栈
- 2026年04月20日
-
哇塞fm网站维护最近国语视频在线观看
哇塞fm网站维护最近国语视频在线观看
- 技术栈
- 2026年04月20日
