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

Javascript之提高React性能的技巧

 更新時(shí)間:2023年04月09日 09:55:50   作者:技術(shù)小張zz  
一些剛開(kāi)始學(xué)習(xí) React,或者從其他框架轉(zhuǎn)入 React 的開(kāi)發(fā)者,一開(kāi)始可能不會(huì)太關(guān)注性能。因?yàn)樾枰恍r(shí)間來(lái)發(fā)現(xiàn)新學(xué)習(xí)的框架的性能缺點(diǎn)。這篇文章主要介紹提高React性能的技巧,感興趣的同學(xué)可以參考閱讀

一些剛開(kāi)始學(xué)習(xí) React,或者從其他框架轉(zhuǎn)入 React 的開(kāi)發(fā)者,一開(kāi)始可能不會(huì)太關(guān)注性能。因?yàn)樾枰恍r(shí)間來(lái)發(fā)現(xiàn)新學(xué)習(xí)的框架的性能缺點(diǎn)。

后來(lái),由于缺乏經(jīng)驗(yàn),這些開(kāi)發(fā)人員在編寫(xiě)代碼時(shí)會(huì)犯一些小錯(cuò)誤,最終會(huì)累積起來(lái)并導(dǎo)致性能下降。此外,他們將很難解決問(wèn)題。

在這里,我們將探討 7 個(gè)技巧,這些技巧將有助于避免構(gòu)建任何類(lèi)型的應(yīng)用程序時(shí)出現(xiàn)的大多數(shù) React 性能問(wèn)題。

1.解決重復(fù)渲染問(wèn)題

我們大多數(shù)人都知道虛擬 DOM 是如何工作的,但最重要的是檢測(cè)何時(shí)觸發(fā)樹(shù)比較。當(dāng)我們可以跟蹤它時(shí),我們可以控制組件的重新渲染,并最終防止意外的性能流。令人驚訝的是,它并不難捕捉。首先,將 React Devtool 擴(kuò)展添加到瀏覽器。

  • 然后打開(kāi)瀏覽器開(kāi)發(fā)者工具(在 Chrome 中是 Option + ? + J(在 macOS 上),或 Shift + CTRL + J(在 Windows/Linux 上)。
  • 選擇組件
  • 點(diǎn)擊設(shè)置圖標(biāo)
  • 并選中“組件渲染時(shí)突出顯示更新”

就是這樣,現(xiàn)在,當(dāng)我們與 UI 交互時(shí),它會(huì)在當(dāng)前重新渲染的元素上顯示綠色邊框。知道了這一點(diǎn),我們就可以分析我們的任何 React 組件并重構(gòu)它們以避免不必要的重新渲染。

2.通過(guò)拆分組件減少重新渲染

如果我們能夠減少意外重新渲染元素的數(shù)量,它將解決 React 中的大部分性能問(wèn)題。

但我們必須首先回答這個(gè)問(wèn)題:“是什么觸發(fā)了重新渲染?”。答案很簡(jiǎn)單,狀態(tài)改變了。

每次組件狀態(tài)發(fā)生變化時(shí),它都會(huì)喚醒樹(shù)比較,也稱(chēng)為協(xié)調(diào),并重新呈現(xiàn)狀態(tài)上下文的元素。

狀態(tài)上下文,是初始化此類(lèi)狀態(tài)的組件。意思是,如果我們有一個(gè)巨大的組件,它有很多狀態(tài)(不需要相互依賴(lài))并且其中一個(gè)狀態(tài)發(fā)生了變化,它將重新渲染整個(gè)組件元素,這絕對(duì)不是我們想要的。

那么,解決方案是什么?解決方法是通過(guò)將組件的一部分和它的一些狀態(tài)移動(dòng)到它自己的子組件中來(lái)分離狀態(tài)上下文,現(xiàn)在,讓我們看一下這個(gè)例子:

假設(shè)我們有一個(gè)帶有搜索過(guò)濾器的表格組件。搜索過(guò)濾器是一個(gè)受控輸入,其狀態(tài)在輸入文本更改后更新。這是它的樣子:

當(dāng)我們開(kāi)始在搜索輸入字段中輸入時(shí)會(huì)發(fā)生什么?

是的,它將重新呈現(xiàn)整個(gè)表格元素。發(fā)生這種情況是因?yàn)檩斎霠顟B(tài)上下文與表組件共享相同的上下文。

現(xiàn)在,讓我們嘗試我們的解決方案,將輸入元素及其狀態(tài)移動(dòng)到一個(gè)單獨(dú)的組件中,并將其注入到表格組件中。

神奇的事情發(fā)生了,表格組件不再重新渲染。我們稍后可以通過(guò)從輸入發(fā)出事件來(lái)控制我們希望輸入影響表格元素的確切時(shí)間來(lái)增強(qiáng)功能。

好的做法是拆分組件以分離狀態(tài)上下文,以避免冗余的重新渲染。

3.什么是實(shí)例重創(chuàng)建,如何避免?

我們已經(jīng)發(fā)現(xiàn)狀態(tài)更改會(huì)觸發(fā)組件重新渲染,但是我們需要考慮另一個(gè)重要的副作用。

當(dāng)狀態(tài)改變和協(xié)調(diào)發(fā)生時(shí),它將重新初始化整個(gè)組件實(shí)例并保持新的狀態(tài)值。這對(duì)我們來(lái)說(shuō)意味著,在協(xié)調(diào)期間,將重新創(chuàng)建所有函數(shù)實(shí)例,以便能夠考慮新的狀態(tài)值,我們不需要它,在大多數(shù)情況下,函數(shù)可以只依賴(lài)于幾個(gè)狀態(tài),我們不想重新創(chuàng)建不依賴(lài)于已更改狀態(tài)的函數(shù)實(shí)例。

這是一個(gè)提高性能的機(jī)會(huì),我們有幾個(gè)解決方案:useCallback 和 useRef。讓我們看個(gè)例子:

const {someState, setSomeState} = useState('')
const {otherState, setOtherState} = useState('')
const foo = () => {console.log(someState)}

這是最常見(jiàn)的例子。我們有依賴(lài)于狀態(tài) someState 的 foo。當(dāng) someState 改變時(shí),它將重新創(chuàng)建 foo 的新實(shí)例。

這段代碼的問(wèn)題是,即使其他一些狀態(tài)發(fā)生變化,比如 otherState,foo 也會(huì)被重新創(chuàng)建,這是我們實(shí)際上不想要的。我們可以使用 useCallback 來(lái)告訴 React 我們的函數(shù)狀態(tài)依賴(lài)是什么,以便更明確地說(shuō)明何時(shí)重新創(chuàng)建實(shí)例:

const {someState, setSomeState} = useState('')
const {otherState, setOtherState} = useState('')
const foo = useCallback(() => {console.log(someState)}, [someState])

在此示例中,我們將依賴(lài)項(xiàng)數(shù)組傳遞給 useCallback 掛鉤。更好的是,foo 將避免其他狀態(tài)更改。

另一種選擇是使用 useRef。useRef——你可以把它想象成和 useState 一樣,但不會(huì)觸發(fā)組件重新渲染(UI 不會(huì)更新)。useRef 沒(méi)有依賴(lài)列表,所以我們需要傳遞 someState as foo 屬性:

const {someState, setSomeState} = useState('')
const {otherState, setOtherState} = useState('')
const foo = useRef((currentSomeState) => {console.log(currentSomeState)}).current;

在這種情況下,我們根本不會(huì)重新創(chuàng)建 foo 實(shí)例。

結(jié)論:使用 useCallback 和 useRef 來(lái)控制函數(shù)實(shí)例的重新創(chuàng)建。

4.不要偷懶懶加載

React 默認(rèn)同步渲染組件。這意味著組件將等到其子項(xiàng)被渲染后再渲染自己。沒(méi)有必要等待,尤其是當(dāng)一些子組件沒(méi)有耦合時(shí)。它可能會(huì)導(dǎo)致頁(yè)面掛起。

假設(shè)我們點(diǎn)擊了一些導(dǎo)航鏈接,假設(shè)將我們重定向到另一個(gè)頁(yè)面。導(dǎo)航將等待所有頁(yè)面組件呈現(xiàn)完成重定向。它會(huì)影響用戶(hù)體驗(yàn),人們不會(huì)等待,只會(huì)離開(kāi)您的網(wǎng)站。

我們需要使頁(yè)面內(nèi)容異步呈現(xiàn),以免損害導(dǎo)航。解決方案是將您的頁(yè)面組件包裝到 React.lazy(() 并告訴 React 完成導(dǎo)航,然后等待頁(yè)面組件完成渲染:

const PageComponent = React.lazy(() => import('./PageComponent'));

稍后我們可以使用在頁(yè)面組件尚未準(zhǔn)備好時(shí),顯示一些加載動(dòng)畫(huà)。

<Suspense fallback={<div>Loading...</div>}>
   <PageComponent />
</Suspense>

這并不意味著我們必須在任何地方都使用 Lazy load 組件,當(dāng)我們?cè)诓粫?huì)對(duì)性能造成太大損害的地方使用它時(shí),它可能會(huì)導(dǎo)致過(guò)度工程。

另一種場(chǎng)景是一些組件可能默認(rèn)隱藏在 UI 中,所以我們不必等待它們。例如模態(tài)窗口、對(duì)話(huà)框、抽屜和可折疊的側(cè)面板。

延遲加載頁(yè)面組件和隱藏的 UI 組件。

5.何時(shí)使用 React 片段?

它經(jīng)常發(fā)生,當(dāng)我們?cè)?JSX 中構(gòu)建一些布局并想要對(duì)我們的元素進(jìn)行分組時(shí),在大多數(shù)情況下我們使用

標(biāo)簽。或者,例如,我們有我們想要移動(dòng)到單獨(dú)組件中的父子 HTML 標(biāo)記:

<ul>
    <li>Item 1</li> <--- | Want to move it to child <Li> |
    <li>Item 2</li> <--- |                               |
</ul>

因此,當(dāng)我們將 <li> 移動(dòng)到單獨(dú)的組件中時(shí),例如:

const Li = () => {
    return (
        <div>
            <li>Item 1</li>
            <li>Item 2</li>
        </div>
    )
}

并改變它:

<ul>
    <Li/>
</ul>

渲染后,它看起來(lái)像這樣:

<ul>
    <div>
        <li>Item 1</li>  
        <li>Item 2</li>    
    </div>
</ul>

這將創(chuàng)建一個(gè)我們不需要的額外<div>節(jié)點(diǎn)。

這將使我們的 DOM 樹(shù)更加嵌套,從而減慢協(xié)調(diào)過(guò)程。

相反, 我們可以將我們的<div>子元素包裝到 Fragment 中。

最初,F(xiàn)ragment 允許您對(duì) DOM 元素進(jìn)行分組,插入后只會(huì)導(dǎo)致一次重排。

在 React 中,F(xiàn)ragment 也會(huì)讓你減少不必要的節(jié)點(diǎn)。當(dāng)你想對(duì)元素進(jìn)行分組時(shí),你唯一需要做的就是使用 Fragment 而不是 <div>:

const Li = () => {
    return (
        <> /* or <React.Fragment>, or <Fragment>*/
            <li>Item 1</li>
            <li>Item 2</li>
        </>
    )
}

就是這樣,就這么簡(jiǎn)單。

如果要對(duì)元素進(jìn)行分組以減少節(jié)點(diǎn)數(shù),請(qǐng)使用 Fragment。

6.避免在列出的元素中使用索引作為鍵

大家都知道,如果沒(méi)有,Eslint 會(huì)強(qiáng)制執(zhí)行在列出的元素中使用鍵,例如:

<ul>
    <li key="1">Item 1</li>  
    <li key="2">Item 2</li>    
</ul>

React 中的關(guān)鍵是唯一標(biāo)識(shí)符,它幫助 React 指向列表中的正確元素并更新正確的元素。如果我們使用索引作為列表中的鍵,比如:

<ul>
    {[1, 2].map((val, index) => <li key={index}>Item {val}</li>)}  
</ul>

我們將元素映射到它的索引。但是如果我們有排序,列表中元素的順序可能會(huì)改變,初始鍵將不再指向正確的元素。

始終使用唯一 id 作為列出元素的鍵,如果對(duì)象沒(méi)有它,您可以使用外部庫(kù)顯式分配,如 uid。

7.避免Spread Props

這是今天的最后一個(gè)修改調(diào)整技巧,已經(jīng)很多了, 你一定見(jiàn)過(guò),甚至自己親手做過(guò)spreading props。就像是:

const Input = ({ onChange, ...props }) => (
    <input {...props} onChange={e => onChange(e.target.value)}/>
);

它不僅迫使您猜測(cè)實(shí)際輸入接收到的屬性是什么,而且還會(huì)在輸入元素中創(chuàng)建一堆您不一定需要的屬性。

讓它明確,并且不要害怕根據(jù)需要傳遞盡可能多的屬性,您總是可以將它們分組到某個(gè)對(duì)象中:

const Input = ({ onChange, inputProps: {value, type, className} }) => (
    <input className={className} type={type} value={value} onChange={e => onChange(e.target.value)}/>
);

很好,現(xiàn)在更具可讀性。

永遠(yuǎn)不要spread props,分別傳遞每個(gè)屬性。

總結(jié)

我想,您可能已經(jīng)知道 Eslint 強(qiáng)制執(zhí)行的一些調(diào)整,但是現(xiàn)在您知道為什么遵循它們很重要了,而且,您可以對(duì)代碼進(jìn)行性能分析,這將為您提供改進(jìn)空間。

以上就是Javascript之提高React性能的技巧的詳細(xì)內(nèi)容,更多關(guān)于Javascript提高React性能的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • 淺談React中組件邏輯復(fù)用的那些事兒

    淺談React中組件邏輯復(fù)用的那些事兒

    這篇文章主要介紹了淺談React中組件邏輯復(fù)用的那些事兒,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-05-05
  • react中ref獲取dom或者組件的實(shí)現(xiàn)方法

    react中ref獲取dom或者組件的實(shí)現(xiàn)方法

    這篇文章主要介紹了react中ref獲取dom或者組件的實(shí)現(xiàn)方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-05-05
  • 淺談React之狀態(tài)(State)

    淺談React之狀態(tài)(State)

    這篇文章主要介紹了淺談React之狀態(tài)(State),小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2018-09-09
  • React創(chuàng)建對(duì)話(huà)框組件的方法實(shí)例

    React創(chuàng)建對(duì)話(huà)框組件的方法實(shí)例

    在項(xiàng)目開(kāi)發(fā)過(guò)程中,對(duì)于復(fù)雜的業(yè)務(wù)選擇功能很常見(jiàn),下面這篇文章主要給大家介紹了關(guān)于React創(chuàng)建對(duì)話(huà)框組件的相關(guān)資料,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2022-05-05
  • React?路由使用示例詳解

    React?路由使用示例詳解

    這篇文章主要介紹了React?路由使用,使用路由時(shí)需要為組件指定一個(gè)路由的path,最終會(huì)以path為基礎(chǔ),進(jìn)行頁(yè)面的跳轉(zhuǎn),具體使用先看個(gè)簡(jiǎn)單示例,該示例比較簡(jiǎn)單就是兩個(gè)Tab頁(yè)面的來(lái)回切換
    2022-05-05
  • React Fiber構(gòu)建beginWork源碼解析

    React Fiber構(gòu)建beginWork源碼解析

    這篇文章主要為大家介紹了React Fiber構(gòu)建beginWork源碼解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-02-02
  • react 國(guó)際化的實(shí)現(xiàn)代碼示例

    react 國(guó)際化的實(shí)現(xiàn)代碼示例

    這篇文章主要介紹了react 國(guó)際化的實(shí)現(xiàn)代碼示例,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2018-09-09
  • React跨路由組件動(dòng)畫(huà)實(shí)現(xiàn)

    React跨路由組件動(dòng)畫(huà)實(shí)現(xiàn)

    在 React 中路由之前的切換動(dòng)畫(huà)可以使用 react-transition-group 來(lái)實(shí)現(xiàn),但對(duì)于不同路由上的組件如何做到動(dòng)畫(huà)過(guò)渡是個(gè)很大的難題,目前社區(qū)中也沒(méi)有一個(gè)成熟的方案,本文給大家分享React跨路由組件動(dòng)畫(huà)實(shí)現(xiàn),感興趣的朋友一起看看吧
    2023-10-10
  • 使用react-color實(shí)現(xiàn)前端取色器的方法

    使用react-color實(shí)現(xiàn)前端取色器的方法

    本文通過(guò)代碼給大家介紹了使用react-color實(shí)現(xiàn)前端取色器的方法,代碼簡(jiǎn)單易懂,對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧
    2021-11-11
  • Remix 后臺(tái)桌面開(kāi)發(fā)electron-remix-antd-admin

    Remix 后臺(tái)桌面開(kāi)發(fā)electron-remix-antd-admin

    這篇文章主要為大家介紹了Remix 后臺(tái)桌面開(kāi)發(fā)electron-remix-antd-admin的過(guò)程示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-04-04

最新評(píng)論