瞧一瞧React Fiber

啥是React Fiber?

React Fiber,簡單來講就是一個從React v16開始引入的新協調引擎,用來實現Virtual DOM的增量渲染。react

說人話:就是一種能讓React視圖更新過程變得更加流暢順滑的處理手法。ajax

咱們都知道:進程大,線程小。而Fiber(纖維)是一種比線程還要細粒度的處理機制。從這個單詞也能夠猜想:React Fiber會很「細」。到底怎麼個細法,咱們接着往下看。瀏覽器

爲何會有React Fiber?

以前說了,React Fiber是爲了讓React的視圖更新過程變得更加流暢順滑。怎麼,以前React的視圖更新不流暢,不順滑了?編輯器

還真是的,在React v16以前,React的視圖更新確實存在很大的性能問題,其中首當其衝的,就是它的同步更新機制函數

在React決定要加載或更新一顆組件樹以前,會大體作出以下一系列動做:調用各組件的生命週期函數 --> 計算和對比Virtual DOM --> 更新真實的DOM樹。這個過程是同步的,也就是說,一旦這個過程開始,它就會一氣呵成跑完,一直到真實DOM樹更新完畢。性能

然而,當組件樹比較龐大時,這種機制的問題就來了:一顆擁有300個組件的組件樹須要所有更新,假設一個組件更新只需耗時1ms,整棵樹更新一次就須要耗時300ms。在這300ms期間,瀏覽器的主線程一直在「專心致志」地忙着更新這顆組件樹(這時函數的調用棧會很是長),對於頁面上的任何操做都是「漠不關心」的。在這期間,假如用戶在一個輸入框敲了幾個字,頁面上也不會有任何反應,由於渲染按鍵輸入結果也須要主線程來作,然而此時主線程正忙着更新組件樹呢。等到300ms結束了,瀏覽器主線程有空了,才把剛剛敲的那幾個字渲染到input輸入框內。spa

太卡了,真的。線程

因爲JavaScript的單線程工做特色,業內一直有個這樣的原則:**任何動做都不要長時間霸佔主線程,若是遲遲不歸還主線程,那麼在這期間程序就無法對其餘輸入做出響應。用戶輸入了卻沒有響應,或者說響應來的很慢,也就是咱們經常說的「卡頓」。顯然,React的同步更新機制在組件樹龐大時就違反了這一原則,犯了大忌。code

這就是React Fiber出現的緣由:爲了解決舊版React視圖更新的性能瓶頸component

React Fiber到底怎麼工做的?

首先,React Fiber並無解決更新龐大組件樹耗時長的問題,實際上總的耗時仍是同樣的長。可是它解決了一個被廣大開發者口誅筆伐的惡行:長時間霸佔主線程不放。

而它解決的方法就是:分片。

它的工做原理是這樣的:把耗時長的更新任務拆解成一個個小的任務分片,每執行完一個小的任務分片,都歸還一次主線程,看看有沒有什麼其餘緊急任務要作。若是在歸還主線程時恰巧發現有緊急任務,那麼會立刻停掉當前更新任務,轉而讓主線程去作緊急任務,等主線程作完緊急任務,再從新作更新任務。(注意⚠️:是從新!不是從上次被打斷的點繼續);若是沒有緊急任務,纔敢惟惟諾諾地繼續作接下來的任務分片。

簡單來講,就是降了視圖更新的優先級,把更新過程碎片化。

如今咱們捋一捋,React Fiber會這樣處理一個更新過程:

  1. 將一個更新過程分爲Reconciliation階段和Commit階段;
  2. 對於Reconciliation階段進行分片處理,這個階段能夠被更緊急的任務打斷,分片任務作到一半可能要重來;
  3. 對於Commit階段,直接一氣呵成把DOM更新完,不能被打斷。

React Fiber對咱們平常開發有什麼影響?

React Fiber在Reconciliation階段可能會調用如下生命週期函數(這也意味着在這個階段的生命週期函數在一次加載和更新過程當中可能會被屢次調用):

  • componentWillMount
  • componentWillUpdate
  • componentWillReceiveProps
  • shouldComponentUpdate

若是你恰巧沒有上react hooks的車,而是使用傳統的類組件進行開發,那麼切記,不要在以上幾個生命週期函數中作只須要作一次的操做(好比:頁面初始化時發起一個ajax請求獲取數據)。

若是你日常使用react hooks進行開發,那沒事了,就當看了個熱鬧。

相關文章
相關標籤/搜索