首頁 web前端 js教程 react元件拆分的重要性

react元件拆分的重要性

Feb 20, 2021 am 11:23 AM
react 組件

react元件拆分的重要性

前言:

React 是一個用於建立使用者介面的 JAVASCRIPT 函式庫。主要用於建立UI,很多人認為 React 是 MVC 中的 V(視圖)。

react採用虛擬DOM技術減少Javascript與真正DOM的交互,提升了前端效能;採用單向資料流機制,父元件透過props將資料傳遞給子元件,這樣讓資料流向一目了然。

一旦元件的props或則state改變,元件及其子元件都會重新re-render和vdom-diff,從而完成資料的流向互動。但是這種機制在某些情況下比如說資料量較大的情況下可能會存在一些效能問題。以下就來分析react的效能瓶頸,並用結合react-addons-perf工具來說明react元件拆分的重要性。

react效能瓶頸

要了解react的效能瓶頸,就需要知道react的渲染流程。它的渲染可以分為兩個階段:

初始元件化
該階段會執行元件及其所有子元件的render方法,從而產生第一版的虛擬dom。

元件更新渲染。
元件的props或state任意發生改變就會觸發元件的更新渲染。預設情況下其也會執行該元件及其所有子元件的render方法來取得新的虛擬dom。

我們說的效能瓶頸指的是元件更新階段的情況。

react元件更新流程

透過上面分析可以知道元件更新具體過程如下:

執行該元件及其所有子元件的render方法取得更新後的虛擬DOM ,即re-render,即使子元件無需更新。

然後對新舊兩份虛擬DOM進行diff來進行元件的更新

在這個過程中,可以透過元件的shouldComponentUpdate方法傳回值來決定是否需要re-render。

react的整個更新渲染流程可以藉用一張圖來加以說明:

react元件拆分的重要性

預設地,元件的shouldComponentUpdate回傳true,即React預設會調用所有元件的render方法來產生新的虛擬DOM, 然後跟著舊的虛擬DOM比較來決定元件最終是否需要更新。

react效能瓶頸

借圖說話,例如下圖是一個元件結構tree,當我們要更新某個子元件的時候,如下圖的綠色元件(從根元件傳遞下來應用在綠色元件上的資料改變):

react元件拆分的重要性

理想情況下,我們只希望關鍵路徑上的元件進行更新,如下圖:

react元件拆分的重要性

#但是,實際效果卻是每個元件都完成re-render和virtual-DOM diff過程,雖然元件沒有變更,這明顯是一種浪費。如下圖黃色部分錶示浪費的re-render和virtual-DOM diff。

react元件拆分的重要性

根據上面的分析,react的效能瓶頸主要表現在:

對於props和state沒有變化的元件,react也要重新產生虛擬DOM及虛擬DOM的diff。

用shouldComponentUpdate來進行效能優化

針對react的效能瓶頸,我們可以透過react提供的shouldComponentUpdate方法來做點優化的事,可以有選擇的進行元件更新,從而提升react的效能,具體如下:

shouldComponentUpdate需要判斷目前屬性和狀態是否和上一次的相同,如果相同則不需要執行後續產生虛擬DOM及其diff的過程,否則需要更新。

(學習影片分享:javascript影片教學

具體可以這麼顯示實作:

shouldComponentUpdate(nextProps, nextState){   return !isEqual(nextProps, this.props) || !isEqual(nextState, this.state)
}
登入後複製

其中,isEqual方法為判斷兩個物件是否相等(指的是其物件內容相等,而非全等)。

透過顯示覆蓋shouldComponentUpdate方法來判斷元件是否需要更新從而避免無用的更新,但是若為每個元件添加該方法會顯得繁瑣,好在react提供了官方的解決方案,具體做法:

方案對元件的shouldComponentUpdate進行了封裝處理,實現對元件的目前屬性和狀態與上一次的進行淺對比,從而決定元件是否需要更新。

react在發展的不同階段提供兩套官方方案:

PureRenderMin
一種是基於ES5的React.createClass創建的元件,配合該形式下的mixins方式來組合PureRenderMixin提供的shouldComponentUpdate方法。當然用ES6創建的元件也能使用該方案。

react元件拆分的重要性

PureComponent
該方案是在React 15.3.0版本發布的針對ES6而增加的一個元件基底類別:React.PureComponent。這明顯對ES6方式創建的組件更加友善。

react元件拆分的重要性

需要指出的是,不管是PureRenderMin還是PureComponent,他們內部的shouldComponentUpdate方法都是淺比較(shallowCompare)props和state物件的,也就是只比較物件的第一層的屬性及其值是不是相同。例如下面state物件變更為如下值:

react元件拆分的重要性

因為state的value被賦予另一個對象,使nextState.value與this.props.value始終不等,導致淺比較通過不了。在實際專案中,這種嵌套的物件結果是很常見的,如果使用PureRenderMin或PureComponent方式時起不到應有的效果。

雖然可以用深比較方式來判斷,但是深比較類似於深拷貝,遞歸操作,性能開銷比較大。

為此,可以對元件盡可能的拆分,讓元件的props和state物件資料達到扁平化,結合使用PureRenderMin或PureComponent來判斷元件是否更新,可以更好地提升react的效能,不需要開發人員過多關心。

元件拆分

元件拆分,在react中就是將元件盡可能的細分,以便於重複使用和最佳化。拆分的具體原則:

盡量使拆分後的元件更容易判斷是否更新

這不太好理解,舉個例子吧:假設我們定義一個父元件,其包含了5000個子組件。有一個輸入框輸入操作,每次輸入一個數字,對應的那個子組件背景色變紅。

react元件拆分的重要性

本例中,輸入框元件和列表子元件有著明顯的不同,一個是動態的,輸入值比較頻繁;一個是相對靜態的,不管input怎麼輸入它就是5000項。輸入框每輸入一個數字都會導致所有元件re-render,這樣就會造成列表子元件不必要的更新。

可以看出,上面列表元件的更新不容易被取消,因為輸入元件和列表子元件的狀態都置於父元件state中,二者共用;react不可能用shouldComponentUpdate的回傳值來使組件一部分組件更新,另一部分不更新。只有把他們拆分為不同的組件,每個組件只關心對應的props。分割的清單元件只關心自己那部分屬性,其他元件導致父元件的更新在清單元件中可以透過判斷自己關心的屬性值狀況來決定是否更新,這樣才能更好地進行元件最佳化。

盡量讓分割元件的props和state資料扁平化

這主要是從元件最佳化的角度考慮的,如果元件不需過度關注效能,可以忽略。

拆分元件之所以扁平化,是因為React提供的最佳化方案PureRenderMin或PureComponent是淺比較元件的props和state來決定是否更新元件。

上面的清單元件中,this.state.items存放的是物件數組,為了更好的判斷每個清單是否需要更新,可以將每個li清單項目單獨拆分為一個清單項目元件,每個列表項相關的props就是items數組中的每個對象,這種扁平化資料很容易判斷是否資料有變化。

元件分割的一個例子

為了這篇文章專門寫了一個關於新增展示Todo清單的事例庫。克隆程式碼到本地可以在本地運行效果。

該事例庫是一個有著5000項的Todo列表,可以刪除並新增Todo項目。此事例展示了組件分割前和分割後的體驗比較情況,可以發現有效能明顯的提升。

下面我們結合react的效能偵測工具react-addons-perf來說明元件拆分的情況。

拆分前的元件TodosBeforeDivision的render部分內容如下:

react元件拆分的重要性

元件拆分前,輸入框輸入字元、增加todo或刪除todo項可以看出有明顯的卡頓現象,如下圖所示:

react元件拆分的重要性

為了弄清楚是什麼原因導致卡頓現象,我們使用chrome的devTool來定位,具體的做法是使用最新版的chrome瀏覽器的Performance選項來完成。先點擊該選項中的record按鈕開始記錄,這時我們在組件輸入框輸入一個字符,然後點擊stop來停止記錄,我們會看到組件從輸入開始到結束這段時間內的一個性能profile。

react元件拆分的重要性

從圖可以看出我們在輸入單一字元時,輸入框的input事件邏輯幾乎佔據整個回應時間,具體的處理邏輯主要是react層面的batchedUpdates方法批次更新清單元件,而不是使用者自訂的邏輯。

那麼,批次更新為啥佔據這麼多時間呢,為了搞清楚原因,我們藉助基於react-addons-perf的chrome插件chrome-react-perf,它以chrome插件的形式輸出分析的結果。

使用該插件需要注意一點的是:

chrome-react-perf插件的使用需要在專案中引入react-addons-perf模組,並必須將其物件掛載到window全域物件的Perf屬性上,否則不能使用。

在devTool工具中選擇Perf選項試圖,點擊start按鈕後其變成stop按鈕,在組件輸入框中輸入一個字符,然後點擊Perf試圖中的stop按鈕,就會得出對應的性能試圖。

react元件拆分的重要性

上圖提供的4個視圖中,Print Wasted對分析效能最有幫組,它表示元件沒有變化但是參與了更新過程,即浪費了re- render和vdom-diff這個過程,是毫無意義的過程。從圖可以看出:TodosBeforeDivision和TodoItem元件分別浪費了167.88ms、144.47ms,完全可以透過分割元件來避免的開銷,這是react效能最佳化重點。

為此我們需要對TodosBeforeDivision元件進行拆分,拆分為一個帶有input和button的動態元件AddTodoForm和一個相對靜態的元件TodoList。二者分別繼承React.PureComponent可以避免不必要的元件更新。

react元件拆分的重要性

其中TodoList元件也需要為每項Todo任務拆分為一個元件TodoItem,這樣每個TodoItem元件的props物件為扁平化的數據,可以充分利用React .PureComponent來進行物件淺比較從而更好地決定元件是否要更新,這樣避免了新增或刪除一個TodoItem項目時,其他TodoItem元件不必更新。

react元件拆分的重要性

這樣拆分後的元件,在用上面的效能偵測工具查看對應的效果:

react元件拆分的重要性

從上面的截圖可以看出,拆分後的組件性能有了上百倍的提升,雖然其中還包含一些其他優化,例如不將function在組件屬性位置綁定this以及常量對象props緩存起來等避免每次re -render時重新產生新的function和新的物件props。

總的來說,對react元件進行拆分對react效能的提升是非常重要的,這也是react效能最佳化的一個方向。

相關推薦:react教學

以上是react元件拆分的重要性的詳細內容。更多資訊請關注PHP中文網其他相關文章!

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

<🎜>:泡泡膠模擬器無窮大 - 如何獲取和使用皇家鑰匙
3 週前 By 尊渡假赌尊渡假赌尊渡假赌
北端:融合系統,解釋
3 週前 By 尊渡假赌尊渡假赌尊渡假赌
Mandragora:巫婆樹的耳語 - 如何解鎖抓鉤
3 週前 By 尊渡假赌尊渡假赌尊渡假赌

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

熱門話題

Java教學
1666
14
CakePHP 教程
1425
52
Laravel 教程
1324
25
PHP教程
1272
29
C# 教程
1251
24
如何安裝Win10舊版元件DirectPlay 如何安裝Win10舊版元件DirectPlay Dec 28, 2023 pm 03:43 PM

不少用戶在玩win10的的一些遊戲的時候總是會遇到一些問題,比如說卡屏和花屏等等情況,這個時候我們是可以採用打開directplay這個功能來解決的,而且功能的操作方法也很簡單。 win10舊版元件directplay怎麼安裝1、在搜尋框裡面輸入「控制台」然後開啟2、檢視方式選擇大圖示3、找到「程式與功能」4、點選左側的啟用或關閉win功能5、選擇舊版這裡的勾選上就可以了

PHP、Vue和React:如何選擇最適合的前端框架? PHP、Vue和React:如何選擇最適合的前端框架? Mar 15, 2024 pm 05:48 PM

PHP、Vue和React:如何選擇最適合的前端框架?隨著互聯網技術的不斷發展,前端框架在Web開發中起著至關重要的作用。 PHP、Vue和React作為三種代表性的前端框架,每一種都具有其獨特的特徵和優勢。在選擇使用哪種前端框架時,開發人員需要根據專案需求、團隊技能和個人偏好做出明智的決策。本文將透過比較PHP、Vue和React這三種前端框架的特徵和使

如何開啟win10舊版組件的設置 如何開啟win10舊版組件的設置 Dec 22, 2023 am 08:45 AM

win10舊版元件是需要使用者自己去設定裡面打開的,因為很多的元件平時都是預設關閉的狀態,首先我們需要進入到設定裡面,操作很簡單,跟著下面的步驟來就可以了win10舊版元件在哪裡開啟1、點選開始,然後點選「win系統」2、點選進入控制台3、再點選下面的程式4、點選「啟用或關閉win功能」5、在這裡就可以選擇你要的開啟了

Angular元件及其顯示屬性:了解非block預設值 Angular元件及其顯示屬性:了解非block預設值 Mar 15, 2024 pm 04:51 PM

Angular框架中元件的預設顯示行為不是區塊級元素。這種設計選擇促進了元件樣式的封裝,並鼓勵開發人員有意識地定義每個元件的顯示方式。透過明確設定CSS屬性 display,Angular組件的顯示可以完全控制,從而實現所需的佈局和響應能力。

Java框架與前端React框架的整合 Java框架與前端React框架的整合 Jun 01, 2024 pm 03:16 PM

Java框架與React框架的整合:步驟:設定後端Java框架。建立專案結構。配置建置工具。建立React應用程式。編寫RESTAPI端點。配置通訊機制。實戰案例(SpringBoot+React):Java程式碼:定義RESTfulAPI控制器。 React程式碼:取得並顯示API回傳的資料。

vue.js vs.反應:特定於項目的考慮因素 vue.js vs.反應:特定於項目的考慮因素 Apr 09, 2025 am 12:01 AM

Vue.js適合中小型項目和快速迭代,React適用於大型複雜應用。 1)Vue.js易於上手,適用於團隊經驗不足或項目規模較小的情況。 2)React的生態系統更豐富,適合有高性能需求和復雜功能需求的項目。

Vue元件開發:彈跳窗元件實作方法 Vue元件開發:彈跳窗元件實作方法 Nov 24, 2023 am 09:28 AM

Vue組件開發:彈跳窗組件實作方法引言:在前端開發中,彈窗組件是一種常見且重要的組件類型。它可以用來在網頁中展示一些提示訊息、確認或輸入框等互動性內容。本文將介紹如何使用Vue框架開發一個簡單的彈跳窗組件,並提供具體的程式碼範例。一、組件結構設計在設計彈窗組件的結構時,我們需要考慮以下幾個要素:彈跳窗標題:用來顯示彈跳窗的標題資訊。彈跳窗內容:用來展示彈跳窗的具體內容。彈

React在HTML中的作用:增強用戶體驗 React在HTML中的作用:增強用戶體驗 Apr 09, 2025 am 12:11 AM

React通過JSX與HTML結合,提升用戶體驗。 1)JSX嵌入HTML,使開發更直觀。 2)虛擬DOM機制優化性能,減少DOM操作。 3)組件化管理UI,提高可維護性。 4)狀態管理和事件處理增強交互性。

See all articles