最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

React Fiber中面試官最關(guān)心的技術(shù)話題

 更新時(shí)間:2023年06月29日 08:59:37   作者:沐華  
這篇文章主要為大家介紹了React Fiber中面試官最關(guān)心的技術(shù)話題解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪

引言

關(guān)于 React Fiber 出來(lái)也有幾年了,可最近面試多了才發(fā)現(xiàn),還是有很多人一知半解,所以本文梳理了一下有關(guān) Fiber、以及這個(gè)話題環(huán)環(huán)相扣,可以延伸的點(diǎn),給大家面試復(fù)習(xí)、查缺補(bǔ)漏,如果你是面試官也可直接拿去提問(wèn)

React Fiber

說(shuō)一下 React Fiber

是指時(shí)間分片嘛,可以把渲染工作切片,優(yōu)化渲染性能的。

因?yàn)?nbsp;React 是函數(shù)式編程嘛,單向數(shù)據(jù)流,需要手動(dòng) setState 來(lái)更新,所以當(dāng)數(shù)據(jù)改變時(shí)會(huì)默認(rèn)全部重新渲染整個(gè)組件樹(shù),而構(gòu)建虛擬 DOM 則是采用同步遞歸的方式,如果組件很復(fù)雜且嵌套深,那么這個(gè)構(gòu)建虛擬 DOM 的過(guò)程就需要很多時(shí)間,而這種任務(wù)默認(rèn)要執(zhí)行完才會(huì)把控制權(quán)交給瀏覽器,一旦執(zhí)行時(shí)間很長(zhǎng),可能就會(huì)地把瀏覽器卡死。

雖然可以用 pureComponent/shouldComponentUpdate/useMemo/useCallback 等方法來(lái)進(jìn)行控制部分更新或緩存,但也是治標(biāo)不治本。而 fiber 是可以使渲染過(guò)程被中斷,可以把控制權(quán)先交還給瀏覽器,讓位高優(yōu)先級(jí)的任務(wù),等瀏覽器空閑時(shí)再恢復(fù)渲染,這樣就不會(huì)顯得卡頓,而是一幀一幀有規(guī)律的執(zhí)行任務(wù),看起來(lái)雖然有點(diǎn)慢,但是一直在慢慢執(zhí)行的

就像一個(gè)房子,組件層級(jí)就像房子的樓層,但是每一層房子頂都破了很多個(gè)洞的,那幾個(gè)方法就像一片瓦,都能蓋一個(gè)小洞,但稍不注意少蓋一個(gè)房間就會(huì)漏水,房間里的人(用戶)就能感知到(卡),而 fiber 就像在破洞下面放了根水管直接通到屋外,雖然看起來(lái)水管彎彎繞繞的,水落地的時(shí)間慢了(執(zhí)行時(shí)間長(zhǎng)了),但房間里的人,就感覺(jué)不到漏水了(屋子還是個(gè)破屋子)

實(shí)在是因?yàn)?nbsp;React 沒(méi)辦法在編譯階段優(yōu)化更多了,所以采用這種方式來(lái)彌補(bǔ)傷害

React Fiber 是怎么實(shí)現(xiàn)的

主要是通過(guò)兩個(gè)原生的 API 來(lái)實(shí)現(xiàn)的 requestAnimationFrame 和 requestIdleCallback

顯示器每秒 60 幀我們看著才不會(huì)感覺(jué)到卡嘛,比如動(dòng)畫(huà)的時(shí)候,一幀的時(shí)間內(nèi)布局和繪制結(jié)束,還有剩余時(shí)間,JS 就會(huì)拿到主線程使用權(quán),如果 JS 某個(gè)任務(wù)執(zhí)行過(guò)長(zhǎng),動(dòng)畫(huà)下一幀開(kāi)始時(shí) JS 還沒(méi)有執(zhí)行完,就會(huì)導(dǎo)致掉幀,出現(xiàn)卡頓。

所以就通過(guò)把 JS 任務(wù)分成更小的任務(wù)塊,分到每一幀上的方式,一幀時(shí)間到先暫停 JS 執(zhí)行,然后下一幀繪制任完成再把主線程交給 JS,在每一幀繪制之前調(diào)用 requestAnimationFrame;在每一幀空間階段,就是一幀動(dòng)畫(huà)任務(wù)完成,下一幀還沒(méi)到開(kāi)始時(shí)間,這中間還有時(shí)間的話就調(diào)用 requetIdleCallback,執(zhí)行它里面的任務(wù)

其他方式能實(shí)現(xiàn)

函數(shù)式編程嘛,generator 就可以控制函數(shù)的運(yùn)行過(guò)程中斷和恢復(fù),就像這樣:

// 任務(wù)列表
const tasks = []
function * run () {
    let task
    while(task = task.shift()) {
        // 如果有高優(yōu)先級(jí)的任務(wù)
        if (hasHighPriorityTask()) {
            // 中斷
            yield
        }
    }
}
// 中斷后恢復(fù)
const iterator = run()
// 這樣就恢復(fù)了
iterator.next()

為什么不直接用 generator

這個(gè)問(wèn)題 React 開(kāi)發(fā)者有在源碼里回答過(guò):

  • 一是因?yàn)?nbsp;React 是迭代的,而使用 generator + yield 的話需要把所有代碼都包裝成這個(gè)形式,非常麻煩,工作量很大
  • 二是 generator 內(nèi)部是有狀態(tài)的,比如一個(gè)函數(shù)里有用到多個(gè) yield 中斷,就像 await 一樣,有時(shí)候后面的會(huì)依賴(lài)前面的結(jié)果,可當(dāng)后面的執(zhí)行前,前面的又更新了,后面就無(wú)法拿到最新的值,這樣就不可控了

所以就自己實(shí)現(xiàn)一個(gè)完全可控的

怎么判斷當(dāng)前是否有高優(yōu)先級(jí)的任務(wù)

這個(gè)據(jù)我所知 JS 好像沒(méi)法判斷,而是按幀的時(shí)間,如果一幀內(nèi)任務(wù)還沒(méi)執(zhí)行完,就中斷當(dāng)前任務(wù),把控制權(quán)交給瀏覽器

瀏覽器什么時(shí)候才有空呢

每秒60幀算,每幀就是 1000/60 = 16.7ms 差不多,每幀任務(wù)執(zhí)行完會(huì)調(diào) requetIdleCallback(callback),并且在 callback 中會(huì)有一個(gè)參數(shù)告訴我們當(dāng)前幀還有多少時(shí)間給我們執(zhí)行任務(wù)

那瀏覽器一幀內(nèi)要做哪些事情

比如布局(layout)、繪制(paint)、JS 的執(zhí)行、處理用戶輸入事件、requestAnimation 調(diào)用等,如果在一幀內(nèi)處理完了這些剩余時(shí)間就用來(lái)執(zhí)行 requetIdleCallback,直到下一幀開(kāi)始

  • 如果瀏覽器很忙,一幀結(jié)束了還沒(méi)執(zhí)行怎么辦

requetIdleCallback(callback, options),還有第二個(gè)參數(shù),里面有個(gè) timeout 字段(毫秒),如果超過(guò)這個(gè)時(shí)間還沒(méi)有被執(zhí)行的話,那么下一幀就會(huì)強(qiáng)制執(zhí)行

  • 就是說(shuō)超時(shí)后一定會(huì)被執(zhí)行咯

也不一定,React 里有 5 個(gè)優(yōu)先級(jí)的等級(jí),高優(yōu)先級(jí)的會(huì)被優(yōu)先執(zhí)行,低優(yōu)先級(jí)的慢慢等下去,等級(jí)是這樣的

  • Immediate: 最高優(yōu)先級(jí),會(huì)馬上執(zhí)行的不能中斷
  • UserBlocking: 這一般是用戶交互的結(jié)果,需要及時(shí)反饋
  • Normal: 普通等級(jí)的,比如網(wǎng)絡(luò)請(qǐng)求等不需要用戶立即感受到變化的
  • Low: 低優(yōu)先級(jí)的,這種任務(wù)可以延后,但最后始終是要執(zhí)行的
  • Idle: 最低等級(jí)的任務(wù),可以被無(wú)限延遲的,比如 console.log()

如果是相同優(yōu)先級(jí)的任務(wù),就會(huì)按推入任務(wù)隊(duì)列的順序來(lái)執(zhí)行

兼容性怎么樣

requetIdleCallback 兼容性是很差的,React 也是通過(guò) messageChannel 模擬實(shí)現(xiàn)的 requetIdleCallback 的功能

除了 MessageChannel 還有沒(méi)有其他類(lèi)似方法

還有一個(gè)功能類(lèi)似的 BroadcastChannel

以上就是React Fiber中面試官最關(guān)心的技術(shù)話題的詳細(xì)內(nèi)容,更多關(guān)于React Fiber面試技術(shù)的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Redux使用方法和基本原理解讀

    Redux使用方法和基本原理解讀

    這篇文章主要介紹了Redux使用方法和基本原理,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-10-10
  • 詳解React-Todos入門(mén)例子

    詳解React-Todos入門(mén)例子

    本篇文章主要介紹了React-Todos入門(mén)例子,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2016-11-11
  • React事件機(jī)制源碼解析

    React事件機(jī)制源碼解析

    這篇文章主要介紹了React事件機(jī)制源碼解析的相關(guān)資料,幫助大家更好的理解和學(xué)習(xí)使用React框架,感興趣的朋友可以了解下
    2021-04-04
  • Vite搭建React項(xiàng)目的方法步驟

    Vite搭建React項(xiàng)目的方法步驟

    這篇文章主要介紹了Vite搭建React項(xiàng)目的方法步驟,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2021-04-04
  • react腳手架構(gòu)建運(yùn)行時(shí)報(bào)錯(cuò)問(wèn)題及解決

    react腳手架構(gòu)建運(yùn)行時(shí)報(bào)錯(cuò)問(wèn)題及解決

    這篇文章主要介紹了react腳手架構(gòu)建運(yùn)行時(shí)報(bào)錯(cuò)問(wèn)題及解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-03-03
  • useCallback和useMemo的正確用法詳解

    useCallback和useMemo的正確用法詳解

    這篇文章主要為大家介紹了useCallback和useMemo的正確用法詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-01-01
  • React tsx生成隨機(jī)驗(yàn)證碼

    React tsx生成隨機(jī)驗(yàn)證碼

    這篇文章主要為大家詳細(xì)介紹了React tsx生成隨機(jī)驗(yàn)證碼,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-04-04
  • React從Class方式轉(zhuǎn)Hooks詳解

    React從Class方式轉(zhuǎn)Hooks詳解

    這篇文章主要介紹了React從Class方式轉(zhuǎn)Hooks詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2021-09-09
  • React Router V6更新內(nèi)容詳解

    React Router V6更新內(nèi)容詳解

    這篇文章主要為大家介紹了React Router V6更新內(nèi)容,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來(lái)幫助
    2021-12-12
  • React中的refs的使用教程

    React中的refs的使用教程

    本篇文章主要介紹了React中的refs的使用教程,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2018-02-02

最新評(píng)論

都江堰市| 澎湖县| 申扎县| 上饶市| 鹤峰县| 商城县| 门源| 通辽市| 方山县| 北辰区| 澜沧| 札达县| 清流县| 会东县| 龙山县| 靖江市| 理塘县| 会昌县| 武清区| 巨野县| 额尔古纳市| 昭觉县| 乳山市| 玛多县| 阿荣旗| 福清市| 莆田市| 龙门县| 和政县| 曲阜市| 西乡县| 敦化市| 渝北区| 江阴市| 铜陵市| 石嘴山市| 饶河县| 甘肃省| 仁怀市| 徐闻县| 昭苏县|