React 避免重渲染

2022-04-06 10:54:09 字數 3376 閱讀 9830

我們可以在 react 元件中的 props 和 state 存放任何型別的資料,通過改變 props 和 state,去控制整個元件的狀態。當 props 和 state 發生變化時,react 會重新渲染整個元件,元件重新渲染的過程可簡化如下圖:

譯者之前對diff的理解是,對於乙個改變 props 的元件,diff能自動計算出元件內部dom樹的不同,然後經過對比,找出真正變化的dom節點,對變化部分進行渲染。這個是錯誤的理解,diff演算法只是用來計算出改變狀態或 props的元件/虛擬節點,而這個元件/虛擬節點,無論多大,它都會重新渲染。 

假設有乙個渲染完成的元件,如下圖:

接下來因為狀態改變,需要重新渲染下圖的綠色的節點,如下圖:

一般的想法是只需要更新下面的三個綠色節點就能夠完成元件的更新

然而!只要元件的 props 或 state 發生了變化就會重新渲染整個元件,因此除了上述的三個綠色節點以外,還需要重新渲染所有的黃色的節點

除了必要渲染的三個節點外,還渲染了其他不必要渲染的節點,這對效能是乙個很大的浪費。如果對於複雜的頁面,這將導致頁面的整體體驗效果非常差。因此要提高元件的效能,就應該想盡一切方法減少不必要的渲染。

shouldcomponentupdate這個函式會在元件重新渲染之前呼叫,函式的返回值確定了元件是否需要重新渲染。函式預設的返回值是 true,意思就是只要元件的 props 或者 state 發生了變化,就會重新構建 virtual dom,然後使用 diff 演算法進行比較,再接著根據比較結果決定是否重新渲染整個元件。函式的返回值為 false 表示不需要重新渲染。 

函式預設返回為 true.

react 官方提供了 purerendermixin 外掛程式,外掛程式的功能就是在不必要的情況下讓函式 shouldcomponentupdate 返回 false, 使用這個外掛程式就能夠減少不必要的重新渲染,得到一定程度上的效能提公升,其使用方法如下:

import purerendermixin from 'react-addons-pure-render-mixin';

class foocomponent extends react.component

render() >foodiv>;}}

我們需要在元件中重寫 shouldcomponentupdate,purerendermixin原始碼中對purerendermixin.shouldcomponentupdate的定義是這樣

shouldcomponentupdate(nextprops, nextstate) 

重寫的方法裡面根據元件的目前的狀態和元件接下來的狀態進行淺比較,如果元件的狀態發生變化則返回結果為 false,狀態沒有發生變化則返回結果為 true

shouldcomponentupdate(nextprops, nextstate) 

在 react 的最新版本裡面,提供了 react.purecomponent 的基礎類,而不需要使用這個外掛程式。 

譯者注:所以在乙個較大的元件決定重渲染的時候,我們可以在每乙個子元件中繫結新的shouldcomponentupdate方法,這樣可以減少子元件重新渲染的次數。 

我們自己可以重寫 shouldcomponentupdate 這個函式,使得其能夠對任何事物進行比較,也就是深比較(通過一層一層的遞迴進行比較),深比較是很耗時的,一般不推薦這麼幹,因為要保證比較所花的時間少於重新渲染的整個元件所花的時間,同時為了減少比較所花的時間我們應該保證 props 和 state 盡量簡單,不要把不必要的屬性放入 state,能夠由其他屬性計算出來的屬性也不要放入 state 中。

對於複雜的資料的比較是非常耗時的,而且可能無法比較,通過使用 immutable.js 能夠很好地解決這個問題,immutable.js 的基本原則是對於不變的物件返回相同的引用,而對於變化的物件,返回新的引用。因此對於狀態的比較只需要使用如下**即可:

shouldcomponentupdate() 

同樣需要我們在子元件中將shouldcomponentupdate方法重寫。

如果乙個元件只和 props 和 state 有關係,給定相同的 props 和 state 就會渲染出相同的結果,那麼這個元件就叫做純元件,換一句話說純元件只依賴於元件的 props 和 state,下面的**表示的就是乙個純元件。

render() }>

div>);}

如果某個子元件的 props 是固定的不會發生變化,我們叫做無狀態元件。在這個元件裡面使用 purerendermixin 外掛程式,能夠保證 shouldcomponentupdate 的返回一直為 false。所以,分清純元件和無狀態元件,在無狀態元件中重寫shouldcomponentupdate方法是最好的選擇。

在寫動態子元件的時候,如果沒有給動態子項新增key prop,則會報乙個警告。這個警告指的是,如果每乙個子元件是乙個陣列或者迭代器的話,那麼必須有乙個唯一的key prop,那麼這個key prop是做什麼的呢? 

我們想象一下,假如需要渲染乙個有5000項的成績排名榜單,而且每隔幾秒就會更新一次排名,其中大部分排名只是位置變了,還有少部分是完全更新了,這時候key就發揮作用了,它是用來標識當前的唯一性的props。現在嘗試來描述這一場景

[, , ]

其中sid是學號,那麼我們來實現成績排名的榜單

import react from 'react';

function rank()>li>

))}ul>)}

我們把key設成了序號,這麼做的確不會報警告了,但這樣是非常低效的做法,這個key是用來做virtual dom diff的,上面的做法相當於用了乙個隨機鍵,那麼不論有沒有相同的項,更新都會重新渲染。 

正確的做法非常簡單,只需要把key的內容換成sid就可以了。 

那麼還有另乙個問題,當key相同的時候,react會怎麼渲染呢,答案是只渲染第乙個相同key的項,且會報乙個警告。

React 避免重新渲染 效能優化

react框架執行的原理 介面受到資料驅動,state 和 props 的改動會造成介面的改動。其中,state 是自身的屬性,props 是父元件提供的引數。如果介面內容很多,很小的資料變化會造成介面的重繪,那麼造成效能的浪費。下面從幾個方面總結一下如何避免重新渲染。state是乙個元件內部的屬性...

react頁面渲染之前 react 渲染順序

工作中要對乙個 做再次更新,可能是渲染後更新或者部分元件渲染之後,對頁面效果做處理 之前對react的理解,僅僅停留在render渲染.這次好好理解了下react的生命週期 1 react元件有三種狀態 mounted 已插入真實的dom updating 正在被渲染 和 unmounted已移除真...

react總結之避免不必要的重複渲染

類元件purecomponent 適當的使用purecomponent建立元件可以提高效能,在使用類元件的時侯,繼承purecomponent元件,它是依賴於傳遞給元件的props進行淺比較,當props發生改變的時候,才會重新渲染元件,既然是淺比較,那麼在state和props每次都發生改變的額時...