總結了如下幾個方面在react上的性能優化react
常見的性能問題場景
web
時刻注意代碼的潛在性能問題
chrome
注意可重構的代碼,組件化
redux
瞭解如何使用工具定位性能問題
canvas
JavaScript 語言採用的是單線程模型,也就是說,全部任務只能在一個線程上完成,一次只能作一件事。若是頁面比較複雜,添加了大量的計算,而且還添加了Canvas(Canvas 是一個很是受歡迎的表現方式,同時也是WebGL的入口。它能繪製圖形,圖片,展現動畫,甚至是處理視頻內容)的繪製,那頁面加載可能會卡頓,有可能會呈現出假死狀態。
數組
解決方案:在Worker中使用OffscreenCanvas或者將頁面渲染時大量的計算放在Worker中。 首先咱們先了解幾個概念(以在Worker中用OffscreenCanvas爲列)
瀏覽器
Workers 是一個Web版的線程——它容許你在幕後運行你的代碼。將你的一部分代碼放到Worker中能夠給你的主線程更多的空閒時間,這能夠提升你的用戶體驗度性能優化
OffscreenCanvas並不依賴DOM。bash
OffscreenCanvas學習文檔。
另外web workers學習文檔請去官網瞭解
框架
總結: 學習成本比較低,在耗性能的計算和渲染放在Worker中,確實能提高用戶體驗度
dom節點層次多,並且深,更改state或者更改redux,致使與該數據無相關的dom節點屢次render。
js處理數據過於複雜。定義的狀態數據層次過於深。致使對比或者遍歷數據消耗性能。
{...this.props} 不要濫用,請只傳遞component須要的props,傳得太多,或者層次傳得太深,都會加劇shouldComponentUpdate裏面的數據比較負擔。
方法綁定的使用
<div onClick={this.tap.bind(this)} />
複製代碼
constructor(props) {
super(props);
this.tap= this.tap.bind(this);
}
複製代碼
tap = ()=>{};
<div onClick={this.tap} />
複製代碼
tap =(value)=> {};
<div onClik={()=>this.tap(value)} />
複製代碼
總結:
1.因爲綁定是在render中執行,而render是會執行屢次的,每次bind和箭頭函數都會產生一個新的函數,於是帶來了額外的開銷
2.使用構造器bind的方法,每一個實例均可以有效地共享函數體,從而更加有效的使用內存。但當要綁定的函數較多時,這種方法又顯得相對的枯燥和無聊。因此,在知道實例很少,函數體不大的前提下,使用箭頭函數更加快捷。
3.綜合三種寫法,第三種是目前最優寫法
數組遍歷map
map裏面添加key,而且key不要使用index(可變的),儘可能使用穩定常量做爲key。使用index做爲key,只是會讓代碼不報錯,其餘一無可取。
每當組件的props或state改變時, React會從新建立一個virtual DOM, 與上一個做對比, 若是發現兩個virtual DOM不徹底相同, 則React就會作reconcile, 把有差別的地方更新到真實的DOM上。
使用常量做爲key
複製代碼
儘可能少用不可控的refs、DOM操做。
props和state的數據儘量簡單明瞭,扁平化。便於數據對比,數組遍歷從而減少帶來的性能消耗。
使用return null而不是CSS的display:none來控制節點的顯示隱藏。保證同一時間頁面的DOM節點儘量的少。
在開發前期能夠根據業務場景將組件分類
這裏咱們就要說一下有狀態組件和無狀態組件的區別了 就如上所說的展現類組件,這種咱們就能夠把它歸類爲無狀態組件,舉個列子
import React from 'react';
const PicModal = props => {
const { title = '', content = '', picUrl = '', deviceName = '' } = props;
return (
<div>
<span>title</span>
<span>content</span>
<span>deviceName</span>
{picUrl !== '' ? <img src={picUrl}/> : null}
</div>
);
};
export default PicModal;
複製代碼
這樣咱們就能夠本身封裝一個modal組件,根據業務場景不斷的迭代優化。 而上面的交互類組件大多數狀況下都是有狀態組件,維護自身的狀態值。可是要實現可複用性,組件之間的耦合度確定是要低的。組件本身控制本身內部的state。這樣setState只用局部更新視圖。減少性能消耗。
注意:千萬不要在父組件定義state,傳值給子組件。
1.下降組件之間的耦合度
2.便於後續的組件迭代
根據業務場景將組件拆分的足夠細。
下面舉一個移動端的列子,web端大多數都會有這種狀況,點擊項目id列表中projectId,projectList改變。
解決方案:組件1和組件2是經過projectId進行聯動。若是咱們拿到這個需求,首先組件化1和2,組件1經過點擊id,在父組件中執行getProjectList方法,從而實現渲染組件2。根據組件1中id的state渲染組件1
這樣父組件與子組件耦合度很低,子組件本身維護本身的狀態值
兄弟組件之間互不影響,經過父組件通訊
若是拆分業務組件的思路不清晰,盲目的將狀態值放在父組件中,這樣耦合度會大大增長,組件的複用性會大大下降。