欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

React并發(fā)更新與性能優(yōu)化解析

 更新時(shí)間:2023年05月29日 10:38:13   作者:卡頌  
這篇文章主要為大家介紹了React并發(fā)更新與性能優(yōu)化解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪

正文

當(dāng)一個(gè)React應(yīng)用邏輯變得復(fù)雜后,組件render花費(fèi)的時(shí)間會(huì)顯著增長(zhǎng)。如果從組件render視圖渲染期間消耗的時(shí)間過(guò)長(zhǎng),用戶就會(huì)感知到頁(yè)面卡頓。

為了解決這個(gè)問(wèn)題,有兩個(gè)方法:

  • 組件render的過(guò)程從同步變?yōu)楫惒?,這樣render過(guò)程頁(yè)面不會(huì)卡死。這就是并發(fā)更新的原理
  • 減少需要render的組件數(shù)量,這就是常說(shuō)的React性能優(yōu)化

通常,對(duì)于不同類型組件,我們會(huì)采取以上不同的方法。比如,對(duì)于下面這樣的有耗時(shí)邏輯的輸入框,方法1更合適(因?yàn)椴l(fā)更新能減少輸入時(shí)的卡頓):

function ExpensiveInput({onChange, value}) {
  // 耗時(shí)的操作
  const cur = performance.now();
  while (performance.now() - cur < 20) {}
  return <input onChange={onChange} value={value}/>;
}

那么,能不能在整個(gè)應(yīng)用層面同時(shí)兼顧這2種方式呢?答案是 —— 不太行。

這是因?yàn)椋瑢?duì)于復(fù)雜應(yīng)用,并發(fā)更新與性能優(yōu)化通常是相悖的。就是本文要聊的 —— 并發(fā)悖論。

從性能優(yōu)化聊起

對(duì)于一個(gè)組件,如果希望他非必要時(shí)不render,需要達(dá)到的基本條件是:props的引用不變。

比如,下面代碼中Child組件依賴fn props,由于fn是內(nèi)聯(lián)形式,所以每次App組件render時(shí)引用都會(huì)變,不利于Child性能優(yōu)化:

function App() {
  return <Child fn={() => {/* xxx */}}/>
}

為了Child性能優(yōu)化,可以將fn抽離出來(lái):

const fn = () => {/* xxx */}
function App() {
  return <Child fn={fn}/>
}

當(dāng)fn依賴某些props或者state時(shí),我們需要使用useCallback

function App({a}) {
  const fn = useCallback(() => a + 1, [a]);
  return <Child fn={fn}/>
}

類似的,其他類型變量需要用到useMemo。

也就是說(shuō),當(dāng)涉及到性能優(yōu)化時(shí),React的代碼邏輯會(huì)變得復(fù)雜(需要考慮引用變化問(wèn)題)。

當(dāng)應(yīng)用進(jìn)一步復(fù)雜,會(huì)面臨更多問(wèn)題,比如:

  • 復(fù)雜的useEffect邏輯
  • 狀態(tài)如何共享

這些問(wèn)題會(huì)與性能優(yōu)化問(wèn)題互相疊加,最終導(dǎo)致應(yīng)用不僅邏輯復(fù)雜,性能也欠佳。

性能優(yōu)化的解決之道

好在,這些問(wèn)題有個(gè)共同的解決方法 —— 狀態(tài)管理。

上文我們聊到,對(duì)于性能優(yōu)化,關(guān)鍵的問(wèn)題是 —— 保持props引用不變。

在原生React中,如果a依賴b,b依賴c。那么,當(dāng)a變化后,我們需要通過(guò)各種方法(比如useCallback、useMemo)保持b、c引用的穩(wěn)定。

做這件事情本身(保持引用不變)對(duì)開發(fā)者來(lái)說(shuō)就是額外的心智負(fù)擔(dān)。那么,狀態(tài)管理是如何解決這個(gè)問(wèn)題的呢?

答案是:狀態(tài)管理庫(kù)自己管理所有原始狀態(tài)以及派生狀態(tài)。

比如:

  • Recoil中,基礎(chǔ)狀態(tài)類型被稱為Atom,其他派生狀態(tài)都是基于Atom組合而來(lái)
  • Zustand中,基礎(chǔ)狀態(tài)都是create方法創(chuàng)建的實(shí)例
  • Redux中,維護(hù)了一個(gè)全局狀態(tài),對(duì)于需要用到的狀態(tài)通過(guò)selector從中摘出來(lái)

這些狀態(tài)管理方案都會(huì)自己維護(hù)所有的基礎(chǔ)狀態(tài)與派生狀態(tài)。當(dāng)開發(fā)者從狀態(tài)管理庫(kù)中引入狀態(tài)時(shí),就能最大限度保持props引用不變。

比如,下例用Zustand改造上面的代碼。由于狀態(tài)a和依賴afn都是由Zustand管理,所以fn的引用始終不變:

const useStore = create(set => ({
  a: 0,
  fn: () => set(state => ({ a: state.a + 1 })),
}))
function App() {
  const fn = useStore(state => state.fn)
  return <Child fn={fn}/>
}

并發(fā)更新的問(wèn)題

現(xiàn)在我們知道,性能優(yōu)化的通用解決途徑是 —— 通過(guò)狀態(tài)管理庫(kù),維護(hù)一套邏輯自洽的外部狀態(tài)(這里的外部是區(qū)別于React自身的狀態(tài)),保持引用不變。

但是,這套外部狀態(tài)最終一定會(huì)轉(zhuǎn)化為React的內(nèi)部狀態(tài)(再通過(guò)內(nèi)部狀態(tài)的變化驅(qū)動(dòng)視圖更新),所以就存在狀態(tài)同步時(shí)機(jī)的問(wèn)題。即:什么時(shí)候?qū)⑼獠繝顟B(tài)與內(nèi)部狀態(tài)同步?

在并發(fā)更新之前的React中,這并不是個(gè)問(wèn)題。因?yàn)楦率峭?、不?huì)被打斷的。所以對(duì)于同一個(gè)外部狀態(tài),在整個(gè)更新過(guò)程中都能保持不變。

比如,在如下代碼中,由于List組件的render過(guò)程不會(huì)打斷,所以list在遍歷過(guò)程中是穩(wěn)定的:

function List() {
  const list = useStore(state => state.list)
  return (
    <ul>
      {list.map(item => <Item key={item.id} data={item}/>}
    </ul>
  )
}

但是,對(duì)于開啟并發(fā)更新的React,更新流程可能中斷,不同的Item組件可能是在中斷前后不同的宏任務(wù)中render,傳遞給他們的data props可能并不相同。這就導(dǎo)致同一次更新,同一個(gè)狀態(tài)(例子中的list)前后不一致的情況。

這種情況被稱為tearing(視圖撕裂)。

可以發(fā)現(xiàn),造成tearing的原因是 —— 外部狀態(tài)(狀態(tài)管理庫(kù)維護(hù)的狀態(tài))與React內(nèi)部狀態(tài)的同步時(shí)機(jī)出問(wèn)題。

這個(gè)問(wèn)題在當(dāng)前React中是很難解決的。退而求其次,為了讓這些狀態(tài)庫(kù)能夠正常使用,React專門出了個(gè)hook —— useSyncExternalStore。用于將狀態(tài)管理庫(kù)觸發(fā)的更新都以同步的方式執(zhí)行,這樣就不會(huì)有同步時(shí)機(jī)的問(wèn)題。

既然是以同步的方式執(zhí)行,那肯定沒(méi)法并發(fā)更新啦~~~

總結(jié)

實(shí)際上,凡是涉及到自己維護(hù)了一個(gè)外部狀態(tài)的庫(kù)(比如動(dòng)畫庫(kù)),都涉及到狀態(tài)同步的問(wèn)題,很有可能無(wú)法兼容并發(fā)更新。

所以,你會(huì)更傾向下面哪種選擇呢:

  • care并發(fā)更新,以前React怎么用,現(xiàn)在就怎么用
  • 根據(jù)項(xiàng)目情況,平衡并發(fā)更新與性能優(yōu)化的訴求

以上就是React并發(fā)更新與性能優(yōu)化解析的詳細(xì)內(nèi)容,更多關(guān)于React并發(fā)更新性能的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • ForwardRef?useImperativeHandle方法demo

    ForwardRef?useImperativeHandle方法demo

    這篇文章主要為大家介紹了ForwardRef?useImperativeHandle方法demo,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-03-03
  • react中useEffect函數(shù)的詳細(xì)用法(最新推薦)

    react中useEffect函數(shù)的詳細(xì)用法(最新推薦)

    useEffect是React中的一個(gè)Hook,用于在函數(shù)組件中處理副作用(如數(shù)據(jù)獲取、訂閱、手動(dòng)更改 DOM 等),useEffect屬于組件的生命周期方法,下面通過(guò)本文給大家分享react中useEffect函數(shù)的詳細(xì)用法,感興趣的朋友跟隨小編一起看看吧
    2024-06-06
  • React Native如何消除啟動(dòng)時(shí)白屏的方法

    React Native如何消除啟動(dòng)時(shí)白屏的方法

    本篇文章主要介紹了React Native如何消除啟動(dòng)時(shí)白屏的方法,詳細(xì)的介紹了解決的方法,具有一定的參考價(jià)值,有興趣的可以了解一下
    2017-08-08
  • 使用React+ts實(shí)現(xiàn)無(wú)縫滾動(dòng)的走馬燈詳細(xì)過(guò)程

    使用React+ts實(shí)現(xiàn)無(wú)縫滾動(dòng)的走馬燈詳細(xì)過(guò)程

    這篇文章主要給大家介紹了關(guān)于使用React+ts實(shí)現(xiàn)無(wú)縫滾動(dòng)的走馬燈詳細(xì)過(guò)程,文中給出了詳細(xì)的代碼示例以及圖文教程,對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2023-08-08
  • 說(shuō)說(shuō)react中引入css的方式有哪些并區(qū)別在哪

    說(shuō)說(shuō)react中引入css的方式有哪些并區(qū)別在哪

    本文主要介紹了說(shuō)說(shuō)react中引入css的方式有哪些并區(qū)別在哪,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2022-04-04
  • React+Node實(shí)現(xiàn)大文件分片上傳、斷點(diǎn)續(xù)傳秒傳思路

    React+Node實(shí)現(xiàn)大文件分片上傳、斷點(diǎn)續(xù)傳秒傳思路

    本文主要介紹了React+Node實(shí)現(xiàn)大文件分片上傳、斷點(diǎn)續(xù)傳秒傳思路,文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-02-02
  • React Refs轉(zhuǎn)發(fā)實(shí)現(xiàn)流程詳解

    React Refs轉(zhuǎn)發(fā)實(shí)現(xiàn)流程詳解

    Refs是一個(gè) 獲取 DOM節(jié)點(diǎn)或React元素實(shí)例的工具,在React中Refs 提供了一種方式,允許用戶訪問(wèn)DOM 節(jié)點(diǎn)或者在render方法中創(chuàng)建的React元素,這篇文章主要給大家介紹了關(guān)于React中refs的一些常見用法,需要的朋友可以參考下
    2022-12-12
  • react+antd4實(shí)現(xiàn)優(yōu)化大批量接口請(qǐng)求

    react+antd4實(shí)現(xiàn)優(yōu)化大批量接口請(qǐng)求

    這篇文章主要為大家詳細(xì)介紹了如何使用react hooks + antd4實(shí)現(xiàn)大批量接口請(qǐng)求的前端優(yōu)化,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以了解下
    2024-02-02
  • 在react中使用tailwind的問(wèn)題

    在react中使用tailwind的問(wèn)題

    這篇文章主要介紹了在react中使用tailwind的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-10-10
  • react組件中過(guò)渡動(dòng)畫的問(wèn)題解決

    react組件中過(guò)渡動(dòng)畫的問(wèn)題解決

    這篇文章主要為大家介紹了react組件中過(guò)渡動(dòng)畫的問(wèn)題解決,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-09-09

最新評(píng)論