面試官:說說react的渲染過程

面試官:說說react的渲染過程

hello,這里是瀟晨,大家在面試的過程中有沒有遇到過一些和react相關的問題呢,比如面試官讓你說說react渲染的過程,這到題目比較開放,也比較考驗大家對react渲染原理以及源碼的整體架構的理解。

  1. 整體流程:

    react源碼3.1

    react的核心可以用ui=fn(state)來表示,更詳細可以用

    const state = reconcile(update);
    const UI = commit(state);
    

    上面的fn可以分為如下一個部分:

    • Scheduler(調度器): 排序優(yōu)先級,讓優(yōu)先級高的任務先進行reconcile
    • Reconciler(協(xié)調器): 找出哪些節(jié)點發(fā)生了改變,并打上不同的Flags(舊版本react叫Tag)
    • Renderer(渲染器): 將Reconciler中打好標簽的節(jié)點渲染到視圖上

    那這些模塊是怎么配合工作的呢

    • 首先jsx經(jīng)過babel的ast詞法解析之后編程React.createElement,React.createElement函數(shù)執(zhí)行之后就是jsx對象,也被稱為virtual-dom。
    • 不管是在首次渲染還是更新狀態(tài)的時候,這些渲染的任務都會經(jīng)過Scheduler的調度,Scheduler會根據(jù)任務的優(yōu)先級來決定將哪些任務優(yōu)先進入render階段,比如用戶觸發(fā)的更新優(yōu)先級非常高,如果當前正在進行一個比較耗時的任務,則這個任務就會被用戶觸發(fā)的更新打斷,在Scheduler中初始化任務的時候會計算一個過期時間,不同類型的任務過期時間不同,優(yōu)先級越高的任務,過期時間越短,優(yōu)先級越低的任務,過期時間越長。在最新的Lane模型中,則可以更加細粒度的根據(jù)二進制1的位置,來決定任務的優(yōu)先級,通過二進制的融合和相交,判斷任務的優(yōu)先級是否足夠在此次render的渲染。Scheduler會分配一個時間片給需要渲染的任務,如果是一個非常耗時的任務,如果在一個時間片之內沒有執(zhí)行完成,則會從當前渲染到的Fiber節(jié)點暫停計算,讓出執(zhí)行權給瀏覽器,在之后瀏覽器空閑的時候從之前暫停的那個Fiber節(jié)點繼續(xù)后面的計算,這個計算的過程就是計算Fiber的差異,并標記副作用。詳細可閱讀往期課件和視頻講解,往期文章在底部。
    • 在render階段:render階段的主角是Reconciler,在mount階段和update階段,它會比較jsx和當前Fiber節(jié)點的差異(diff算法指的就是這個比較的過程),將帶有副作用的Fiber節(jié)點標記出來,這些副作用有Placement(插入)、Update(更新)、Deletetion(刪除)等,而這些帶有副作用Fiber節(jié)點會加入一條EffectList中,在commit階段就會遍歷這條EffectList,處理相應的副作用,并且應用到真實節(jié)點上。而Scheduler和Reconciler都是在內存中工作的,所以他們不影響最后的呈現(xiàn)。
    • 在commit階段:會遍歷EffectList,處理相應的生命周期,將這些副作用應用到真實節(jié)點,這個過程會對應不同的渲染器,在瀏覽器的環(huán)境中就是react-dom,在canvas或者svg中就是reac-art等。

    另外我們也可以從首次渲染和更新的時候看在render和commit這兩個子階段是如果工作的:

    • mount時:
      1. render階段會根據(jù)jsx對象構建新的workInProgressFiber樹,不太了解Fiber雙緩存的可以查看往期文章 Fiber架構,然后將相應的fiber節(jié)點標記為Placement,表示這個fiber節(jié)點需要被插入到dom樹中,然后會這些帶有副作用的fiber節(jié)點加入一條叫做Effect List的鏈表中。
      2. commit階段會遍歷render階段形成的Effect List,執(zhí)行鏈表上相應fiber節(jié)點的副作用,比如Placement插入,或者執(zhí)行PassiveuseEffect的副作用)。將這些副作用應用到真實節(jié)點上
    • update時:
      1. render階段會根據(jù)最新狀態(tài)的jsx對象對比current Fiber,再構建新的workInProgressFiber樹,這個對比的過程就是diff算法,diff算法又分成單節(jié)點的對比和多節(jié)點的對比,不太清楚的同學參見之前的文章 diff算法 ,對比的過程中同樣會經(jīng)歷收集副作用的過程,也就是將對比出來的差異標記出來,加入Effect List中,這些對比出來的副作用例如:Placement(插入)、Update(更新)、Deletion(刪除)等。
      2. commit階段同樣會遍歷Effect List,將這些fiber節(jié)點上的副作用應用到真實節(jié)點上
    react源碼3.2

視頻講解(高效學習):點擊學習

往期react源碼解析文章:

1.開篇介紹和面試題

2.react的設計理念

3.react源碼架構

4.源碼目錄結構和調試

5.jsx&核心api

6.legacy和concurrent模式入口函數(shù)

7.Fiber架構

8.render階段

9.diff算法

10.commit階段

11.生命周期

12.狀態(tài)更新流程

13.hooks源碼

14.手寫hooks

15.scheduler&Lane

16.concurrent模式

17.context

18事件系統(tǒng)

19.手寫迷你版react

20.總結&第一章的面試題解答

?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容