React Fiber 瞭解一下

舊版React中,更新過程是同步的,這可能會導致性能問題。

當React決定要更新組件樹時,會做很多事,比如調用各個組件的生命週期函數,計算和比對Virtual DOM,最後更新DOM樹,這整個過程是同步進行的,也就是說只要一個加載或者更新過程開始,一鼓作氣運行到底,中途絕不停歇。表面上看,這樣的設計也是挺合理的,因爲更新過程不會有任何I/O操作嘛,完全是CPU計算,所以無需異步操作,的確只要一路狂奔就行了,但是,當組件樹比較龐大的時候,問題就來了。

假如更新一個組件需要1毫秒,如果有200個組件要更新,那就需要200毫秒,在這200毫秒的更新過程中,瀏覽器那個唯一的主線程都在專心運行更新操作,無暇去做任何其他的事情。想象一下,在這200毫秒內,用戶往一個input元素中輸入點什麼,敲擊鍵盤也不會獲得響應,因爲渲染輸入按鍵結果也是瀏覽器主線程的工作,但是瀏覽器主線程被React佔着呢,抽不出空,最後的結果就是用戶敲了按鍵看不到反應,等React更新過程結束之後,咔咔咔那些按鍵一下子出現在input元素裏了。

這就是所謂的界面卡頓,很不好的用戶體驗。

所以Fiber 架構就是用異步的方式解決舊版本同步遞歸導致的性能問題。

破解JavaScript中同步操作時間過長的方法其實很簡單——分片。

把一個耗時長的任務分成很多小片,每一個小片的運行時間很短,雖然總時間依然很長,但是在每個小片執行完之後,都給其他任務一個執行的機會,這樣唯一的線程就不會被獨佔,其他任務依然有運行的機會

維護每一個分片的數據結構,就是Fiber。

module.exports = {
  NoWork: 0, // No work is pending.
  SynchronousPriority: 1, // For controlled text inputs. Synchronous side-effects.
  AnimationPriority: 2, // Needs to complete before the next frame.
  HighPriority: 3, // Interaction that needs to complete pretty soon to feel responsive.
  LowPriority: 4, // Data fetching, or result from updating stores.
  OffscreenPriority: 5, // Won't be visible but do the work in case it becomes visible.
};

React Fiber 每個工作單元運行時有6種優先級

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章