前端領域的數據結構與算法解讀 - fiber

前一段時間我分享了幾篇關於《數據結構與算法在前端領域的應用》的文章。前端

文章連接:react

這一次咱們順着前面的內容,講一些經典的數據結構與算法,本期咱們來說一下時下比較火熱的React fibergit

這部份內容相對比較硬核和難以消化,不然 React 團隊也不會花費兩年的時間來搞這一個東西。建議你們多讀幾遍。程序員

關於我

我是一個對技術充滿興趣的程序員, 擅長前端工程化,前端性能優化,前端標準化等。github

作過.net, 搞過Java,如今是一名前端工程師。面試

除了個人本職工做外,我會在開源社區進行一些輸出和分享,GitHub 共計得到1.5W star。比較受歡迎的項目有leetcode題解 , 宇宙最強的前端面試指南個人第一本小書算法

fiber - 一個用於增量更新的數據結構

前面個人文章提到過 fiber 是一種數據結構,而且是一種鏈式的數據結構。前端工程化

fiber 是爲了下一代調和引擎而引入的一種新的數據結構,而下一代調和引擎最核心的部分就是 「增量渲染」。爲了明白這個「增量渲染」,咱們須要打一點小小的基礎。瀏覽器

分片執行

爲了作到上面我提到的「增量渲染」,咱們首先要可以停下來。 以前 React 的更新 UI 的策略是自頂向下進行渲染,若是沒有人工的干涉,React 實際上會更新到 全部的子組件,這在大多數狀況下沒有問題。性能優化

然而隨着項目愈來愈複雜,這種弊端就很是明顯了。單純看這一點,Vue 在這方面作的更好, Vue 提供了更加細粒度的更新組件的方式,甚至無需用戶參與。 這是二者設計理念上的差別,不關乎 好壞,只是適用場景不同罷了。

值得一提的是,Vue 的這種細粒度監聽和更新的方式,其實是內存層面和計算層面的權衡。 社區中一些新的優秀框架,也借鑑了 Vue 的這種模式,而且完成了進一步的進化,對不一樣的類型進行劃分, 並採起不一樣的監聽更新策略,其實是一種更加「智能「的取捨罷了。

言歸正傳,咱們如何才能作到」增量更新「呢?

  • 首先你要可以在進行到中途的時候停下來
  • 你可以繼續剛纔的工做,換句話說能夠重用以前的計算結果

實現這兩點靠的正是咱們今天的主角 fiber,稍後咱們再講。

好比以前 React 執行了一個 100ms 的更新過程,對於新的調和算法, 會將這個過程劃分爲多個過程,固然每一份時間極可能是不一樣的。

因爲總時間不會減小,咱們設置還增長了調度(上面我提到的兩條)的代碼, 所以單純從總時間上,甚至是一種倒退。可是爲何用戶會感受到更快了呢? 這就是下面咱們要講的調度器。

三大核心組件 - Scheduler, Reconciliation, Renderer

事實上, React 核心的算法包含了三個核心部分,分別是Scheduler,ReconciliationRenderer

  • scheduler 用於決定什麼時候去執行。

前面提到了,整個更新過程要比以前的作法要長。總時間變長的狀況下,用戶感受性能更好的緣由在於 scheduler。 對於用戶而言,界面交互,動畫,界面更新的優先級其實是不同的。

經過保證高優先級的事件的執行,好比用戶輸入,動畫。 可讓用戶有性能很好的感受。

作到這一點實際上原理很簡單,即便前面提到的 chunks,再加上咱們給每個任務分配一個優先級, 從而保證 chunks 的執行順序中高優先級的在前面。

瀏覽器實際上本身也會對一些事件區分優先級。

  • Reconciliation 決定哪部分須要更新,以及如何「相對最小化」完成更新過程。 這部分算法主要上衣基於VDOM這種數據結構來完成的。

這部分的算法實際上就是一個「閹割版的最小編輯樹算法」。

  • renderer 使用 Reconciliation 的計算結果,而後將這部分差別,最小化更新到視圖。能夠是 DOM,也能夠是 native, 理論上能夠是任何一種渲染容器。

在 DOM 中,這部分的工做由 React-DOM 來完成。它會生成一些 DOM 操做的 API,從而去完成一些反作用, 這裏指的是更新 DOM。

fiber - 一個虛擬調用棧

實際上,fiber 作的事情就是將以前 react 更新策略進行了重構。

以前的更新策略是從頂向下,經過調用棧的形式保存已經更新的信息。 這自己沒有問題, 可是這和咱們剛纔想要實現的效果是不匹配的,咱們須要 chunks 的效果。 而以前的策略是從頂到下一口氣執行完,不斷 push stack,而後 pop stack,直到 stack 爲空。

fiber 正是模擬了調用棧,而且經過鏈表來從新組織,一方面使得咱們能夠實現 chunks 的功能。 另外一方面能夠和 VDOM 進行很好的對應和映射。

v = f(d)

這是我從 React 官方介紹 fiber 的一個地方抄來的公式。

它想表達的是 react 是一個視圖管理框架,而且是數據驅動的,惟一的數據會驅動產生惟一的視圖。

咱們能夠把每個組件都當作一個 view,然而咱們的工做就是計算全部的組件的最新的 view。

那麼 fiber 是如何完成「增量更新」呢? 祕訣就是它至關於「從新實現了瀏覽器調用棧」。

咱們來看一下,fiber 是如何實現傳統調用棧的功能的。

fiber 和 傳統調用棧的區別

傳統的調用棧,咱們實際上將生成 view 的工做放到棧裏面執行,瀏覽器的棧有一個特色就是 「你給它一個任務,它必須一口氣執行完」。

而 fiber 因爲是本身設計的,所以能夠沒有這個限制。 具體來講,二者的對應關係以下:

傳統調用棧            fiber

  子函數          component type
 函數嵌套              child
  參數                props
 返回地址             parent
  返回值          DOM elements

複製代碼

用圖來表示的話,大概是這樣:

其中具體的算法,我預計會在個人從零開始開發一個 React 中更新。

總結

本篇文章介紹了fiber,fiber實際上是一種用於增量更新的數據結構。 是爲了下一代調和引擎而引入的一種新的數據結構,而下一代調和引擎最核心的部分就是 「增量渲染」。

咱們介紹了幾個基本概念和組件,包括分片執行, react三大核心組件 - Scheduler, Reconciliation, Renderer。

最後咱們說了「fiber實際上就是一個虛擬調用棧」,並結合傳統調用棧的特色和弊端,講解了fiber是如何組織, 從而改進了傳統調用棧帶來的問題的。

關注我

最近我從新整理了下本身的公衆號,而且我還給他換了一個名字《腦洞前端》,它是一個幫助你打開大前端新世界大門的鑰匙 🔑,在這裏你能夠聽到新奇的觀點,看到一些技術嘗新,還會收到系統性總結和思考。

我會盡可能經過圖的形式來闡述一些概念和邏輯,幫助你們快速理解,圖解前端是個人目標。

以後個人文章同步到微信公衆號 腦洞前端 ,您能夠關注獲取最新的文章,或者和我進行交流。

gongzhonghao

交流羣

如今仍是初級階段,須要你們的意見和反饋,爲了減小溝通成本,我組建了交流羣。你們能夠掃碼進入

QQ 羣

qq-group-chat

微信羣

JavaScript

(因爲微信的限制,100 我的以上只能邀請加入, 你能夠添加個人機器人回覆「大前端」拉你進羣)

相關文章
相關標籤/搜索