一、為什麼要用 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、提交:提交階段任務不能中斷