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

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

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

正文

當一個React應用邏輯變得復雜后,組件render花費的時間會顯著增長。如果從組件render視圖渲染期間消耗的時間過長,用戶就會感知到頁面卡頓。

為了解決這個問題,有兩個方法:

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

通常,對于不同類型組件,我們會采取以上不同的方法。比如,對于下面這樣的有耗時邏輯的輸入框,方法1更合適(因為并發(fā)更新能減少輸入時的卡頓):

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

那么,能不能在整個應用層面同時兼顧這2種方式呢?答案是 —— 不太行。

這是因為,對于復雜應用,并發(fā)更新與性能優(yōu)化通常是相悖的。就是本文要聊的 —— 并發(fā)悖論。

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

對于一個組件,如果希望他非必要時不render,需要達到的基本條件是:props的引用不變。

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

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

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

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

fn依賴某些props或者state時,我們需要使用useCallback

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

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

也就是說,當涉及到性能優(yōu)化時,React的代碼邏輯會變得復雜(需要考慮引用變化問題)。

當應用進一步復雜,會面臨更多問題,比如:

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

這些問題會與性能優(yōu)化問題互相疊加,最終導致應用不僅邏輯復雜,性能也欠佳。

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

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

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

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

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

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

比如:

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

這些狀態(tài)管理方案都會自己維護所有的基礎狀態(tài)與派生狀態(tài)。當開發(fā)者從狀態(tài)管理庫中引入狀態(tài)時,就能最大限度保持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ā)更新的問題

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

但是,這套外部狀態(tài)最終一定會轉化為React的內部狀態(tài)(再通過內部狀態(tài)的變化驅動視圖更新),所以就存在狀態(tài)同步時機的問題。即:什么時候將外部狀態(tài)與內部狀態(tài)同步?

在并發(fā)更新之前的React中,這并不是個問題。因為更新是同步、不會被打斷的。所以對于同一個外部狀態(tài),在整個更新過程中都能保持不變。

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

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

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

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

可以發(fā)現,造成tearing的原因是 —— 外部狀態(tài)(狀態(tài)管理庫維護的狀態(tài))與React內部狀態(tài)的同步時機出問題。

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

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

總結

實際上,凡是涉及到自己維護了一個外部狀態(tài)的庫(比如動畫庫),都涉及到狀態(tài)同步的問題,很有可能無法兼容并發(fā)更新。

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

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

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

相關文章

  • 詳解react-redux插件入門

    詳解react-redux插件入門

    這篇文章主要介紹了詳解react-redux插件入門,小編覺得挺不錯的,現在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-04-04
  • React前端框架實現原理的理解

    React前端框架實現原理的理解

    React是前端開發(fā)每天都用的前端框架,自然要深入掌握它的原理。我用?React?也挺久了,這篇文章就來總結一下我對?react?原理的理解,有需要的朋友可以借鑒參考下,希望能夠有所幫助
    2022-07-07
  • 關于React中setState同步或異步問題的理解

    關于React中setState同步或異步問題的理解

    相信很多小伙伴們都一直在疑惑,setState 到底是同步還是異步。本文就詳細的介紹一下React中setState同步或異步問題,感興趣的可以了解一下
    2021-11-11
  • React類組件和函數組件對比-Hooks的簡介

    React類組件和函數組件對比-Hooks的簡介

    Hook?是?React?16.8?的新增特性,它可以讓我們在不編寫class的情況下,?使用state以及其他的React特性(比如生命周期,這篇文章主要介紹了React類組件和函數組件對比-Hooks的介紹及初體驗,需要的朋友可以參考下
    2022-11-11
  • 一文帶你搞懂react hooks的類型聲明

    一文帶你搞懂react hooks的類型聲明

    這篇文章主要給帶大家搞清楚react hooks的類型聲明,如果有同學還不清楚react hooks的類型聲明,來看本文就對了,文中通過代碼示例介紹的非常詳細,需要的朋友可以參考下
    2023-07-07
  • React Mobx狀態(tài)管理工具的使用

    React Mobx狀態(tài)管理工具的使用

    這篇文章主要介紹了React Mobx狀態(tài)管理工具的使用,MobX是一個狀態(tài)管理庫,它會自動收集并追蹤依賴,開發(fā)人員不需要手動訂閱狀態(tài),當狀態(tài)變化之后MobX能夠精準更新受影響的內容,另外它不要求state是可JSON序列化的,也不要求state是immutable
    2023-02-02
  • create-react-app項目配置全解析

    create-react-app項目配置全解析

    這篇文章主要為大家介紹了create-react-app項目配置全解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-06-06
  • react的hooks的用法詳解

    react的hooks的用法詳解

    這篇文章主要介紹了react的hooks的用法詳解,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-10-10
  • React首頁加載速度優(yōu)化小結

    React首頁加載速度優(yōu)化小結

    本文詳細介紹了如何優(yōu)化一個加載緩慢的React項目,從刪除未使用的導入、刪除不必要的依賴項、刪除sourceMap、使用Terser壓縮以及使用SplitChunksPlugin分包,再到React的懶加載優(yōu)化,感興趣的可以了解一下
    2026-01-01
  • JavaScript的React框架中的JSX語法學習入門教程

    JavaScript的React框架中的JSX語法學習入門教程

    這篇文章主要介紹了JavaScript的React框架中的JSX語法學習入門教程,React是由Facebook開發(fā)并開源的高人氣js框架,需要的朋友可以參考下
    2016-03-03

最新評論

凌海市| 长白| 沙田区| 通海县| 吉木乃县| 贵定县| 玉屏| 页游| 石城县| 和田县| 墨脱县| 双流县| 柳江县| 青川县| 高要市| 石门县| 贵德县| 岑巩县| 云梦县| 江山市| 江阴市| 泽普县| 白河县| 全椒县| 靖边县| 广丰县| 望都县| 蒲江县| 南康市| 萝北县| 叙永县| 宜兰市| 罗平县| 文登市| 井研县| 海安县| 莱州市| 凭祥市| 开江县| 宽城| 塘沽区|