前一段時間我分享了幾篇關於《數據結構與算法在前端領域的應用》的文章。前端
文章連接:react
這一次咱們順着前面的內容,講一些經典的數據結構與算法,本期咱們來說一下時下比較火熱的React fiber
。git
這部份內容相對比較硬核和難以消化,不然 React 團隊也不會花費兩年的時間來搞這一個東西。建議你們多讀幾遍。程序員
我是一個對技術充滿興趣的程序員, 擅長前端工程化,前端性能優化,前端標準化等。github
作過.net, 搞過Java,如今是一名前端工程師。面試
除了個人本職工做外,我會在開源社區進行一些輸出和分享,GitHub 共計得到1.5W star。比較受歡迎的項目有leetcode題解 , 宇宙最強的前端面試指南 和 個人第一本小書算法
前面個人文章提到過 fiber 是一種數據結構,而且是一種鏈式的數據結構。前端工程化
fiber 是爲了下一代調和引擎而引入的一種新的數據結構,而下一代調和引擎最核心的部分就是 「增量渲染」。爲了明白這個「增量渲染」,咱們須要打一點小小的基礎。瀏覽器
爲了作到上面我提到的「增量渲染」,咱們首先要可以停下來。 以前 React 的更新 UI 的策略是自頂向下進行渲染,若是沒有人工的干涉,React 實際上會更新到 全部的子組件,這在大多數狀況下沒有問題。性能優化
然而隨着項目愈來愈複雜,這種弊端就很是明顯了。單純看這一點,Vue 在這方面作的更好, Vue 提供了更加細粒度的更新組件的方式,甚至無需用戶參與。 這是二者設計理念上的差別,不關乎 好壞,只是適用場景不同罷了。
值得一提的是,Vue 的這種細粒度監聽和更新的方式,其實是內存層面和計算層面的權衡。 社區中一些新的優秀框架,也借鑑了 Vue 的這種模式,而且完成了進一步的進化,對不一樣的類型進行劃分, 並採起不一樣的監聽更新策略,其實是一種更加「智能「的取捨罷了。
言歸正傳,咱們如何才能作到」增量更新「呢?
實現這兩點靠的正是咱們今天的主角 fiber,稍後咱們再講。
好比以前 React 執行了一個 100ms 的更新過程,對於新的調和算法, 會將這個過程劃分爲多個過程,固然每一份時間極可能是不一樣的。
因爲總時間不會減小,咱們設置還增長了調度(上面我提到的兩條)的代碼, 所以單純從總時間上,甚至是一種倒退。可是爲何用戶會感受到更快了呢? 這就是下面咱們要講的調度器。
事實上, React 核心的算法包含了三個核心部分,分別是Scheduler,
, Reconciliation
,Renderer
。
前面提到了,整個更新過程要比以前的作法要長。總時間變長的狀況下,用戶感受性能更好的緣由在於 scheduler。 對於用戶而言,界面交互,動畫,界面更新的優先級其實是不同的。
經過保證高優先級的事件的執行,好比用戶輸入,動畫。 可讓用戶有性能很好的感受。
作到這一點實際上原理很簡單,即便前面提到的 chunks,再加上咱們給每個任務分配一個優先級, 從而保證 chunks 的執行順序中高優先級的在前面。
瀏覽器實際上本身也會對一些事件區分優先級。
VDOM
這種數據結構來完成的。這部分的算法實際上就是一個「閹割版的最小編輯樹算法」。
在 DOM 中,這部分的工做由 React-DOM 來完成。它會生成一些 DOM 操做的 API,從而去完成一些反作用, 這裏指的是更新 DOM。
實際上,fiber 作的事情就是將以前 react 更新策略進行了重構。
以前的更新策略是從頂向下,經過調用棧的形式保存已經更新的信息。 這自己沒有問題, 可是這和咱們剛纔想要實現的效果是不匹配的,咱們須要 chunks 的效果。 而以前的策略是從頂到下一口氣執行完,不斷 push stack,而後 pop stack,直到 stack 爲空。
fiber 正是模擬了調用棧,而且經過鏈表來從新組織,一方面使得咱們能夠實現 chunks 的功能。 另外一方面能夠和 VDOM 進行很好的對應和映射。
這是我從 React 官方介紹 fiber 的一個地方抄來的公式。
它想表達的是 react 是一個視圖管理框架,而且是數據驅動的,惟一的數據會驅動產生惟一的視圖。
咱們能夠把每個組件都當作一個 view,然而咱們的工做就是計算全部的組件的最新的 view。
那麼 fiber 是如何完成「增量更新」呢? 祕訣就是它至關於「從新實現了瀏覽器調用棧」。
咱們來看一下,fiber 是如何實現傳統調用棧的功能的。
傳統的調用棧,咱們實際上將生成 view 的工做放到棧裏面執行,瀏覽器的棧有一個特色就是 「你給它一個任務,它必須一口氣執行完」。
而 fiber 因爲是本身設計的,所以能夠沒有這個限制。 具體來講,二者的對應關係以下:
傳統調用棧 fiber
子函數 component type
函數嵌套 child
參數 props
返回地址 parent
返回值 DOM elements
複製代碼
用圖來表示的話,大概是這樣:
其中具體的算法,我預計會在個人從零開始開發一個 React 中更新。
本篇文章介紹了fiber,fiber實際上是一種用於增量更新的數據結構。 是爲了下一代調和引擎而引入的一種新的數據結構,而下一代調和引擎最核心的部分就是 「增量渲染」。
咱們介紹了幾個基本概念和組件,包括分片執行, react三大核心組件 - Scheduler, Reconciliation, Renderer。
最後咱們說了「fiber實際上就是一個虛擬調用棧」,並結合傳統調用棧的特色和弊端,講解了fiber是如何組織, 從而改進了傳統調用棧帶來的問題的。
最近我從新整理了下本身的公衆號,而且我還給他換了一個名字《腦洞前端》,它是一個幫助你打開大前端新世界大門的鑰匙 🔑,在這裏你能夠聽到新奇的觀點,看到一些技術嘗新,還會收到系統性總結和思考。
我會盡可能經過圖的形式來闡述一些概念和邏輯,幫助你們快速理解,圖解前端是個人目標。
以後個人文章同步到微信公衆號 腦洞前端 ,您能夠關注獲取最新的文章,或者和我進行交流。
如今仍是初級階段,須要你們的意見和反饋,爲了減小溝通成本,我組建了交流羣。你們能夠掃碼進入
(因爲微信的限制,100 我的以上只能邀請加入, 你能夠添加個人機器人回覆「大前端」拉你進羣)