react性能優化

1.(單個react組件性能優化)render裏面儘量減少新建變量和bind函數,傳遞參數是儘量減少傳遞參數的數量。***

在這裏插入圖片描述
第一種是在構造函數中綁定this,第二種是在render()函數裏面綁定this,第三種就是使用箭頭函數,都能實現上述方法;但是第一種的性能最好。

因爲第一種,構造函數每一次渲染的時候只會執行一遍;
而第二種方法,在每次render()的時候都會重新執行一遍函數;
第三種方法的話,每一次render()的時候,都會生成一個新的箭頭函數,即使兩個箭頭函數的內容是一樣的。

2.多個react組件性能優化,key的優化

react組件在裝載過程中,react通過在render方法在內存中產生一個樹形結構,樹上的節點代表一個react組件或者原生的Dom元素,這個樹形結構就是我們所謂的Vitural Dom,react根據這個來渲染產生瀏覽器的Dom樹。

react在更新階段對比原有的Vitural Dom和新生成的Vitural Dom,找出不同之處,在根據不同來渲染Dom樹。
在這裏插入圖片描述

我們想把A組件更新成B組件,react在做比較的時候,發現最外面的根結點不一樣,直接就廢掉了之前的

節點,包括裏面的子節點,這是一個巨大的浪費,所以在開發過程中,我們應該儘量避免上面的情況,不要將包裹節點的類型隨意改變
多個子組件情況
簡單來說,其實這一個Key就是react組件的身份證號。
在這裏插入圖片描述
不過現在,react也會提醒我們不要忘記使用key,如果沒有加,在瀏覽器中會報錯。
在這裏插入圖片描述
**

3.不要使用內聯函數定義

**
如果我們使用內聯函數,每次調用「render」函數時都會創建一個新的函數實例。
當 React 進行虛擬 DOM diffing 時,它每次都會找到一個新的函數實例;因此在渲染階段它會會綁定新函數並將舊實例扔給垃圾回收。
因此直接綁定內聯函數就需要額外做垃圾回收和綁定到 DOM 的新函數的工作。
在這裏插入圖片描述
上面的函數創建了內聯函數。每次調用 render 函數時都會創建一個函數的新實例,render 函數會將該函數的新實例綁定到該按鈕。
此外最後一個函數實例會被垃圾回收,大大增加了 React 應用的工作量。
所以不要用內聯函數,而是在組件內部創建一個函數,並將事件綁定到該函數本身。這樣每次調用 render 時就不會創建單獨的函數實例了,參考組件如
在這裏插入圖片描述

4.避免使用內聯樣式屬性

使用內聯樣式時瀏覽器需要花費更多時間來處理腳本和渲染,因爲它必須映射傳遞給實際 CSS 屬性的所有樣式規則。
將內聯樣式附加到組件。添加的內聯樣式是 JavaScript 對象而不是樣式標記。
樣式 backgroundColor 需要轉換爲等效的 CSS 樣式屬性,然後才應用樣式。這樣就需要額外的腳本處理和 JS 執行工作。
更好的辦法是將 CSS 文件導入組件

5.避免 componentWillMount() 中的異步請求

componentWillMount 是在渲染組件之前調用的。這個函數用的不多,可用來配置組件的初始配置,但使用 constructor 方法自己也能做到。
該方法無法訪問 DOM 元素,因爲組件還沒掛載上來。

一些開發人員認爲這個函數可以用來做異步數據 API 調用,但其實這沒什麼好處。由於 API 調用是異步的,因此組件在調用 render 函數之前不會等待 API 返回數據。於是在初始渲染中渲染組件時沒有任何數據。
在這裏插入圖片描述
在上面的代碼中,我們正在進行異步調用以獲取數據。由於數據調用是異步的,需要一段時間才能獲取到。

在檢索數據時 React 會觸發組件的 render 函數。因此第一個調用的渲染仍然不包含它所需的數據。

這樣一開始渲染組件沒有數據,然後檢索數據,調用 setState,還得重新渲染組件。在 componentWillMount 階段進行 AJAX 調用沒有好處可言。
我們應避免在此函數中發出 Async 請求。這些函數和調用可以延遲到 componentDidMount 生命週期事件裏。

6.在 Constructor 的早期綁定函數

當我們在 React 中創建函數時,我們需要使用 bind 關鍵字將函數綁定到當前上下文。綁定可以在構造函數中完成,也可以在我們將函數綁定到 DOM 元素的位置上完成。兩者之間似乎沒有太大差異,但性能表現是不一樣的。
在這裏插入圖片描述
在上面的代碼中,我們在 render 函數的綁定期間將函數綁定到按鈕上。問題在於,每次調用 render 函數時都會創建並使用綁定到當前上下文的新函數,但在每次渲染時使用已存在的函數效率更高。優化方案如下:
在這裏插入圖片描述
最好在構造函數調用期間使用綁定到當前上下文的函數覆蓋 handleButtonClick 函數。這將減少將函數綁定到當前上下文的開銷,無需在每次渲染時重新創建函數,從而提高應用的性能。

7.優化 React 中的條件渲染

很多情況下在我們可能會渲染或不渲染特定元素,這時可以用條件渲染。
在這裏插入圖片描述
優化爲
在這裏插入圖片描述

8.不要在 render 方法中導出數據

Render 方法是 React 開發人員最熟悉的生命週期事件。和其他生命週期事件不一樣的是,我們的核心原則是將 render() 函數作爲純函數。

純函數意味着我們應該確保 setState 和查詢原生 DOM 元素等任何可以修改應用狀態的東西不會被調用。該函數永遠不該更新應用的狀態。

更新組件狀態的問題在於,當狀態更新時會觸發另一個 render 循環,後者在內部會再觸發一個 render 循環,以此類推。
在這裏插入圖片描述
在上面的代碼中,每次調用 render 函數時都會更新狀態。狀態更新後組件將立即重新渲染。因此更新狀態會導致 render 函數的遞歸調用。
render 函數應保持純淨,以確保組件以一致的方式運行和渲染

9.用 CSS 動畫代替 JavaScript 動畫

在 HTML 5 和 CSS 3 出現之前,動畫曾經是 JavaScript 的專屬,但隨着 HTML 5 和 CSS 3 的引入情況開始變化。現在動畫甚至可以由 CSS 3 來處理了。
我們可以制定一些規則:
如果 CSS 可以實現某些 JS 功能,那就用 CSS。
理由如下:

  1. 破損的 CSS 規則和樣式不會導致網頁損壞,而 JavaScript 則不然。
  2. 解析 CSS 是非常便宜的,因爲它是聲明性的。我們可以爲樣式並行創建 內存中的表達,可以推遲樣式屬性的計算,直到元素繪製完成。
  3. 爲動畫加載 JavaScript 庫的成本相對較高,消耗更多網絡帶寬和計算時間。
  4. 雖然 JavaScript 可以提供比 CSS 更多的優化,但優化過的 JavaScript 代碼也可能卡住 UI 並導致 Web 瀏覽器崩潰。

10.React 組件的服務端渲染

服務端渲染可以減少初始頁面加載延遲。
我們可以讓網頁從服務端加載初始頁面,而不是在客戶端上渲染。這樣對 SEO 非常有利。服務端渲染是指第一個組件顯示的內容是從服務器本身發送的,而不是在瀏覽器級別操作。之後的頁面直接從客戶端加載。
這樣我們就能把初始內容放在服務端渲染,客戶端只按需加載部分頁面。
其好處包括:

  1. 性能:初始頁面內容和數據是從服務器本身加載的,因此我們不需要添加加載器和下拉列表,而是等待初始頁面加載完畢後再加載初始組件。
  2. SEO 優化:爬蟲在應用初始加載時查找頁面內容。在客戶端渲染時初始 Web 頁面不包含所需的組件,這些組件需要等 React 腳本等文件加載完畢後才渲染出來。

11.shouldComponentUpdate避免組件無意義渲染

state有時候很不聽話,在某些時候,我不想他渲染,偏偏react非常智能的幫我們重複渲染。
比如最常見的就是傳遞的對象爲空,組件依舊渲染了一次或者多次。
使用shouldComponentUpdate鉤子,根據具體的業務狀態,減少不必要的props變化導致的渲染。如一個不用於渲染的props導致的update。
另外, 也要儘量避免在shouldComponentUpdate 中做一些比較複雜的操作, 比如超大數據的pick操作等。
shouldComponentUpdate是react提供的生命週期函數,他發生在接收到新的props的時候。
在這裏插入圖片描述
組件生命週期是有順序的,首先掛載組件,掛載成功完成第一次渲染,然後傳遞新的props,則會觸發componentWillRecevieProps,執行重新渲染的週期,直至渲染完成。

組件生命週期是有順序的,首先掛載組件,掛載成功完成第一次渲染,然後傳遞新的props,則會觸發componentWillRecevieProps,執行重新渲染的週期,直至渲染完成。
在你的組件內部加上這段代碼
component.js
在這裏插入圖片描述
這裏用到了_.isEqual和_.isEmpty,.isEqual判斷當前傳進來的值和下一次傳遞的值是不是相等,是則返回true,.isEmpty判斷當前傳遞進來的對象是不是爲空,爲空則返回true。
.isEqual和.isEmpty是 lodash 插件裏面的函數,這是個輕巧的JavaScript函數插件,可以處理多種常見的數據操作,當然還有一個更多功能的插件。 在你的react項目的入口js導入lodash,因爲lodash函數是全局的,所以只需要在入口導入一次即可。 • 合理設計state,不需要渲染的state,儘量使用實例成員變量。 不需要渲染的props,合理使用context機制,或公共模塊(比如一個單例服務)變量來替換。 • 拆分組件是有利於複用和組件優化的。 • 生成虛擬DOM並進行比對發生在render()後,而不是render()前。