一、为什么要用 fiber架构
在react16 之前,react是用 diff 算法对vitrulDom进行对比更新渲染,这种 diff 算法对比 如果遇到需要大量时间执行的方法任务时,就会造成页面卡顿
二、什么是 fiber 架构
fiber架构简单点说就是 任务切片(一个耗时任务在浏览器空闲时,分多次执行),这样就在用户感官上页面流畅不卡顿
浏览器卡顿判断标准:
正常情况下人眼感受到的 每秒 60帧,也就是16.6ms/帧,如果超过超过这个值,就会感受到卡顿,如果说某个任务耗时超过16.6ms就会造成页面暂时卡顿
fiber怎么做:
fiber 架构会把一个要耗时任务会分解成无数个执行只需大概5ms的任务片段,在浏览器空闲时执行
如何判断浏览器是否空闲:
浏览器有个API叫 requestIdleCallback
requestIdleCallback
回调函数: 回调函数是在主线程空闲时被调用的函数。每次调用时,都会传入一个IdleDeadline
对象,该对象提供一个timeRemaining()
方 法,用来检测当前帧中剩余的空闲时间。
注意:requestIdleCallback 是一个宏任务,在事件列表中是最后执行的
but!!!react 并没有使用浏览器原生的 requestIdleCallback 方法(因为浏览器兼容,目前只要chorm支持)
react 而是用了 MessageChannel 进行任务调度
什么是 MessageChannel?
MessageChanne设计初衷是为了方便 我们在不同的上下文之间进行通讯,例如web Worker
,iframe
它提供了两个端口(port1 和 port2),通过这些端口,消息可以在两个独立的线程之间双向传递
const channel = new MessageChannel(); const port1 = channel.port1; const port2 = channel.port2;// 设置 port1 的消息处理函数 port1.onmessage = (event) => {console.log('Received by port1:', event.data);port1.postMessage('Reply from port1'); // 向 port2 发送回复消息 };// 设置 port2 的消息处理函数 port2.onmessage = (event) => {console.log('Received by port2:', event.data); };// 通过 port2 发送消息给 port1 port2.postMessage('Message from port2');
react 是实现是复杂的,他要设计任务执行优先级(优先级设计包含过期时间、是否用户操作、组件优先级等)
三、fiber 如何中断任务
fiber 分片任务执行的两个阶段:
1、调度:任务中断可以在调度阶段进行
2、提交:提交阶段任务不能中断