东莞万江网站制作台州网站搜索优化
东莞万江网站制作,台州网站搜索优化,html5标准网站建设,网页设计代码简单优先级类型
React内部对于优先级的管理#xff0c;贯穿运作流程的4个阶段#xff08;从输入到输出#xff09;#xff0c;根据其功能的不同#xff0c;可以分为3种类型#xff1a; 1 #xff09;fiber优先级(LanePriority) 位于 react-reconciler包#xff0c;也就是L…优先级类型
React内部对于优先级的管理贯穿运作流程的4个阶段从输入到输出根据其功能的不同可以分为3种类型 1 fiber优先级(LanePriority) 位于 react-reconciler包也就是Lane(车道模型) 2 调度优先级(SchedulerPriority) 位于scheduler包 3 优先级等级(ReactPriorityLevel) 位于react-reconciler包中的 SchedulerWithReactIntegration.js负责上述2套优先级体系的转换. Lane 是在 react17.0.0的新特性.
Lane(车道模型) 英文单词lane翻译成中文表示车道航道的意思所以很多文章都将Lanes模型称为车道模型 Lane模型的源码在 ReactFiberLane.js,源码中大量使用了位运算 首先引入对Lane的解释, 这里简单概括如下 1 Lane类型被定义为二进制变量利用了位掩码的特性在频繁运算的时候占用内存少计算速度快. Lane和Lanes就是单数和复数的关系代表单个任务的定义为Lane,代表多个任务的定义为Lanes 2 Lane是对于expirationTime的重构以前使用expirationTime表示的字段都改为了lanerenderExpirationTime - renderlanes
update.expirationTime - update.lane
fiber.expirationTime - fiber.lanes
fiber.childExpirationTime - fiber.childLanes
root.firstPendingTime and root.lastPendingTime - fiber.pendingLanes3 使用Lanes模型相比expirationTime模型的优势 Lanes把任务优先级从批量任务中分离出来可以更方便的判断单个任务与批量任务的优先级是否重叠 // 判断单task与batchTask的优先级是否重叠
// 1.通过expirationTime判断
const isTaskIncludedInBatch priorityOfTask priorityOfBatch;
// 2.通过Lanes判断
const isTaskIncludedInBatch (task batchOfTasks) ! 0;// 当同时处理一组任务该组内有多个任务且每个任务的优先级不一致
// 1. 如果通过expirationTime判断需要维护一个范围在Lane重构之前源码中就是这样比较的
const isTaskIncludedInBatch taskPriority highestPriorityInRange taskPriority lowestPriorityInRange;
// 2. 通过Lanes判断
const isTaskIncludedInBatch (task batchOfTasks) ! 0;Lanes使用单个32位二进制变量即可代表多个不同的任务 也就是说一个变量即可代表一个组(group) 如果要在一个group中分离出单个task,非常容易 在expirationTime模型设计之初react体系中还没有 Suspense 异步渲染的概念 现在有如下场景有3个任务其优先级ABC,正常来讲只需要按照优先级顺序执行就可以了 但是现在情况变了A和C任务是CPU密集型而B是IO密集型(Suspense会调用远程api,算是IO任务) 即A(cpu)B(IO)C(cpu).此时的需求需要将任务B从group中分离出来先处理cpu任务A和C //从group中删除或增加task// 通过expirationTime实现
// 维护一个链表按照单个task的优先级顺序进行插入
// 删除单个task(从链表中删除一个元素)
task. prev.next task.next;
//2增加单个task(需要对比当前task的优先级插入到链表正确的位置上)
let current queue;
while (task.expirationTime current.expirationTime) {current current.next;
}
task.next current.next;
current.next task;
//3比较task是否在group中
const isTaskIncludedInBatch taskPriority highestPriorityInRange taskPriority lowestPriorityInRang;
//2.通过Lanes实现
//1)删除单个task
batchOfTasks ~task;
//2增加单个task
batchOfTasks | task;
//3比较task是否在group中
const isTaskIncludedInBatch (task batchOfTasks) ! 0;Lanes是一个不透明的类型只能在ReactFiberLane.js这个模块中维护 如果要在其他文件中使用只能通过 ReactFiberLane.js 中提供的工具函数来使用 分析车道模型的源码(ReactFiberLane.js中)可以得到如下结论 1.可以使用的比特位一共有31位2.共定义了18种车道(Lane/Lanes)变量每一个变量占有1个或多个比特位分别定义为Lane和Lanes类型.3.每一种车道(Lane/Lanes)都有对应的优先级所以源码中定义了18种优先级(LanePriority).4.占有低位比特位的Lane变量对应的优先级越高 最高优先级为 SynclanePriority 对应的车道为 Synclane 0b0000000000000000000000000000001 最低优先级为 OffscreenLanePriority 对应的车道为 OffscreenLane 0b1000000000000000000000000000000
位运算 什么是位运算程序中的所有数在计算机内存中都是以二进制的形式储存的。 位运算就是直接对整数在内存中的二进制位进行操作。 比如 0 在二进制中用 0 表示我们用 0000 代表1 在二进制中用 1 表示我们用 0001 代表 那么先看两个位运算符号 和 | 对于每一个比特位两个操作数都为 1 时结果为 1否则为 0| 对于每一个比特位两个操作数都为0时结果为 0否则为 1我们看一下两个 1 0 和 1 | 0如上 1 0 0, 1 | 0 1 参考 0 00001 0001-------------0 1 0000 0再参考 0 0000
1 0001
----------------
0 | 1 0001 1使用一张表格详细说明
运算符用法描述与 a b如果两位都是1则设置每位为1或 | a | b 如果两位之一为1则设置每位为1异或 ^a^b如果两位只有一位为1则设置每位为1非 ~~ a反转操作数的比特位, 即0变成1, 1变成0左移()a b 将a的二进制形式向左移b( 32)比特位, 右边用0填充 有符号右移()ab将a的二进制形式向右移b(32)比特位丢弃被移除的位左侧以最高位来填充无符号右移()ab将a的二进制形式向右移b(32)比特位丢弃被移除的位并用0在左侧填充
位运算的一个使用场景
比如有一个场景下会有很多状态常量A,B,C…,这些状态在整个应用中在一些关键节点中做流程控制比如if(value A) {// TODO..
}如上判断value等于常量A,那么进入到if的条件语句中此时是value属性是简单的一对一关系但是实际场景下value可能是好几个枚举常量的集合也就是一对多的关系那么此时value可能同时代表A和B两个属性如下图所示 这时候如果按照下面的代码来写就会很麻烦if(value A || value B) {// TODO..
}此时的问题就是如何用一个value表示A和B两个属性的集合这个时候位运算就派上用场了因为可以把一些状态常量用32位的二进制来表示这里也可以用其他进制比如const A 0b0000000000000000000000000000001 // 优先级最高
const B 0b0000000000000000000000000000010
const C 0b0000000000000000000000000000100 // 优先级最低通过移位的方式让每一个常量都单独占一位这样在判断一个属性是否包含常量的时候可以根据当前位数的1和0来判断这样如果一个值即代表A又代表B那么就可以通过位运算的 | 来处理就有 AB A | B 0b0000000000000000000000000000011那么如果把AB的值赋予给value,那么此时的value就可以用来代表A和B此时当然不能直接通过等于或者恒等来判断value是否为A或者B,此时就可以通过来判断。具体实现如下const A 0b0000000000000000000000000000001
const B 0b0000000000000000000000000000010
const C 0b0000000000000000000000000000100
const N 0b0000000000000000000000000000000
const value A | B
console.log((value A ) ! N) // true
console.log((value B ) ! N) // true
console.log((value C ) ! N ) // false位运算在 react 中的应用
export const NoLanes /* */ 0b0000000000000000000000000000000;
const SyncLane /* */ 0b0000000000000000000000000000001;const InputContinuousHydrationLane /* */ 0b0000000000000000000000000000010;
const InputContinuousLane /* */ 0b0000000000000000000000000000100;const DefaultHydrationLane /* */ 0b0000000000000000000000000001000;
const DefaultLane /* */ 0b0000000000000000000000000010000;const TransitionHydrationLane /* */ 0b0000000000000000000000000100000;
const TransitionLane /* */ 0b0000000000000000000000001000000;如上 SyncLane 代表的数值是1它却是最高的优先级 也即是说lane的代表的数值越小此次更新的优先级就越大 在新版本的React中还有一个新特性就是render阶段可能被中断在这个期间会产生一个更高优先级的任务 那么会再次更新lane属性这样多个更新就会合并这样一个lane可能需要表现出多个更新优先级 我们来看一下React是如何通过位运算分离出优先级的 function getHighestPriorityLane(lanes) {return lanes -lanes;
}如上就是通过 lanes -lanes 分离出最高优先级的任务的我们来看一下具体的流程 比如SyncLane和InputContinuousLane合并之后的任务优先级lane为SyncLane 0b0000000000000000000000000000001InputContinuousLane 0b0000000000000000000000000000100lane SyncLane|InputContinuousLanelane 0b0000000000000000000000000000101那么通过 lanes -lanes 分离出 SyncLane首先我们看一下 -lanes,在二进制中需要用补码表示为-lane 0b1111111111111111111111111111011那么接下来执行 lanes -lanes 看一下 的逻辑是如果两位都是1则设置改位为1否则为0那么 lane -lane, 只有一位最后一位全是1所有合并后的内容为lane -lane 0b0000000000000000000000000000001 可以看得出来lane-lane的结果是SyncLane,所以通过lane-lane就能分离出最高优先级的任务 const SyncLane 0b0000000000000000000000000000001
const InputContinuousLane 0b0000000000000000000000000000100
const lane SyncLane | InputContinuousLane
console.log((lane -lane) SyncLane ) // true
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/90319.shtml
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!