Open Reaper622 opened 5 years ago
在 React 中,JS 执行和渲染引擎是为互斥关系的,即若 JS 在执行代码时,则渲染引擎会停止部署。如果调用栈过长,加上中间一些复杂的操作,就可能导致长时间的阻塞而给渲染引擎带来阻塞,因此调度由此而生。
React调度主要依靠一个内容:任务的expriationTime
expriationTime
expriationTime主要由两部分组成:当前时间+一个常量(常量根据任务优先级改变)
当前时间
一个常量
当前时间由performance.now()方法提供。react内部当前的优先级有五种
performance.now()
Immediate
UserBlocking
Normal
Low
Idle
该函数的回调方法会在浏览器的空闲时期依次调用, 可以让我们在事件循环中执行一些任务,并且不会对像动画和用户交互这样延迟敏感的事件产生影响。
同时由于requestIdleCallback的兼容性差异,react实现了自己的 requestIdleCallback
requestIdleCallback
它的核心是在浏览器空闲时且是渲染后再调用次回调方法,它内部使用的定时器为requestAnimationFrame,因为它更具有准确度,因为它会在每次重绘前执行,但是页面处于后台状况时回调函数不会执行,补救措施是在后台状况时使用setTimeout。
requestAnimationFrame
setTimeout
注意: 在两个定时器的内部会相互取消掉对方。
浏览器会有支持帧率,如果操作时间都大于一帧「60FPS下为16.67ms」,那么就会存在掉帧的情况,就会影响用户的体验,但如果操作时间没有超过一帧,我就认为当下存在空闲时间让我们执行任务。
expirationTime
React 调度
实现调度
expirtationTime
React调度主要依靠一个内容:任务的
expriationTime
expriationTime
主要由两部分组成:当前时间
+一个常量
(常量根据任务优先级改变)当前时间由
performance.now()
方法提供。react内部当前的优先级有五种Immediate
立即执行优先级,需要同步执行的任务。UserBlocking
用户阻塞型优先级(250ms后过期),需要作为用户交互结果的任务(比如点击事件)Normal
普通优先级(5s后过期),不必让用户立即感受到的更新。Low
低优先级(10s后过期),可以推迟但最终仍然要完成的任务。Idle
空闲优先级(永不过期),不必运行的任务。requestIdleCallback
同时由于
requestIdleCallback
的兼容性差异,react实现了自己的requestIdleCallback
它的核心是在浏览器空闲时且是渲染后再调用次回调方法,它内部使用的定时器为
requestAnimationFrame
,因为它更具有准确度,因为它会在每次重绘前执行,但是页面处于后台状况时回调函数不会执行,补救措施是在后台状况时使用setTimeout
。浏览器会有支持帧率,如果操作时间都大于一帧「60FPS下为16.67ms」,那么就会存在掉帧的情况,就会影响用户的体验,但如果操作时间没有超过一帧,我就认为当下存在空闲时间让我们执行任务。
调度的流程
expirationTime
,高优先级的任务会打断低优先级的任务。requestAnimationFrame
启动定时器,在重绘前调用方法。