摘要:單個組件性能優(yōu)化里面盡量減少新建變量和函數(shù)的使用,盡量減少傳遞參數(shù)的數(shù)量在中綁定函數(shù),無非就是下面三種第一種是在構(gòu)造函數(shù)中綁定,第二種是在函數(shù)里面綁定,第三種就是使用箭頭函數(shù),上述方法都能實現(xiàn)的綁定。
1. 單個react組件性能優(yōu)化 1.1 render里面盡量減少新建變量和bind函數(shù)的使用,盡量減少傳遞參數(shù)的數(shù)量
在render中綁定函數(shù),無非就是下面三種:
render() { return (1 2 this.handleClick()}>3) }
第一種是在構(gòu)造函數(shù)中綁定this,第二種是在render()函數(shù)里面綁定this,第三種就是使用箭頭函數(shù),上述方法都能實現(xiàn)this的綁定。
但是哪一種方法的性能最好,是我們要考慮的問題。毫無疑問第一種的性能最好。
第一種方法,構(gòu)造函數(shù)每渲染一次便會執(zhí)行一遍;
第二種方法,在每次render()的時候都會重新執(zhí)行一遍函數(shù);
第三種方法,每一次render()的時候,都會生成一個新的箭頭函數(shù),即使兩個箭頭函數(shù)的內(nèi)容是一樣的。
react判斷是否需要進行render是淺層比較,簡單來說就是通過===來判斷的,如果state或者prop的類型是字符串或者數(shù)字,只要值相同,那么淺層比較就會認為其相同;
但是如果前者的類型是復雜的對象的時候,我們知道對象是引用類型,淺層比較只會認為這兩個prop是不是同一個引用,如果不是,哪怕這兩個對象中的內(nèi)容完全一樣,也會被認為是兩個不同的prop。
舉個例子:
當我們給組件App名為style的prop賦值;
使用這種方法,每一次渲染都會被認為是一個style這個prop發(fā)生了變化,因為每一次都會產(chǎn)生一個對象給style。
如果想要讓react渲染的時候認為前后對象類型prop相同,則必須要保證prop指向同一個javascript對象,改進如下:
const appStyle = { color: "red" }; //這個初始化只執(zhí)行一次,不要放在render中,可以放在構(gòu)造函數(shù)中1.2 定制shouldComponentUpdate函數(shù)生命周期函數(shù)shouldComponentUpdate是決定react組件什么時候能夠重新渲染的函數(shù),但是這個函數(shù)默認的實現(xiàn)方式就是簡單的返回一個true。也就是說,默認每次更新的時候都要調(diào)用所用的生命周期函數(shù),包括render函數(shù),重新渲染。
看看下面這個例子:
class App extends React.Component { constructor(props) { super(props); this.state = { count = 2, name = "apple", } this.handleClick = this.handleClick.bind(this); this.handleName = this.handleName.bind(this); } this.handleClick() { // ... } this.handleName() { // ... } render() { return (數(shù)量,{this.state.count}); } } class Child extends React.Component { render() { console.log("render了一次"); return (我想吃,{this.props.title}
); } }我們寫了兩個組件,App和Child組件,并寫兩個方法,一個改變App中的count的值,一個是改變name,我們在Child的render中打印了每次是否執(zhí)行。
不出意外,雖然Child組件里的title值沒有改變,但是還是render了。
為了進一步優(yōu)化這個問題,我們這樣改Child組件:
class Child extends React.Component { shouldComponentUpdate(nextProps,nextState) { if(nextProps.title == this.props.title) { return false; } return true; } render() { console.log("render了一次"); return (我想吃,{this.props.title}
); } }只有當Child的title值發(fā)生改變的時候,組件才會去render。
在最新的react中,react給我們提供了React.PureComponent,官方也在早期提供了名為react-addons-pure-render-mixin插件來重新實現(xiàn)shouldComponentUpdate生命周期方法。
class Child extends React.PureComponent { // shouldComponentUpdate(nextProps,nextState) { // if(nextProps.title == this.props.title) { // return false; // } // return true; // } render() { console.log("render了一次"); return (我想吃,{this.props.title}
); } }通過上述的方法的效果也是和我們先前定制shouldComponentUpdate的效果是一致的。
但是我們要注意的是,這里的PureRender是淺比較的,因為深比較的場景是相當昂貴的。所以我們要注意我們在1.1中說到的一些注意點:不要直接為props設(shè)置對象或者數(shù)組、不要將方法直接綁定在元素上,因為其實函數(shù)也是對象。
1.3 Immutable.jsjavascript中的對象一般都是可變的,因為使用了引用賦值,新的對象簡單的引用了原始對象,改變新對象將影響到原始對象。
舉個例子:
student = { age : 1 }; school = student; school.age = 2;當我們給school.age賦值后,會發(fā)現(xiàn)student.a也變成了2,雖然我們可以通過深拷貝與淺拷貝解決這個問題,但是這樣做非常的昂貴,對cpu和內(nèi)存會造成浪費。
這里就需要用到Immutable,通過Immutable創(chuàng)建的Immutable Data一旦被創(chuàng)建,就不能再更改。對Immutable對象進行修改、添加或刪除操作,都會返回一個新的Immutable對象。
下面是三個比較重要且用到的數(shù)據(jù)結(jié)構(gòu)
Map:鍵值對集合,對應Object,ES6中也有專門的Map對象
List:有序可重復列表,對應于Array
ArraySet:有序且不可重復的列表
我們可以看一個例子:
使用Map生成一個immutable對象:
import { Map, is } from "immutable"; let a = Map({ "name": "apple", "list": Map({name: "orange"}) }) let b = a.set("name","banana"); console.log(a.get("course") === b.get("course")); // 返回true console.log(a === b); // 返回falseImmutable.is 比較的是兩個對象的 hashCode 或 valueOf(對于JavaScript對象)。由于immutable內(nèi)部使用了Trie數(shù)據(jù)結(jié)構(gòu)來存儲,只要兩個對象的 hashCode 相等,值就是一樣的。這樣的算法避免了深度遍歷比較,性能非常好。
Immutable優(yōu)點:
減少內(nèi)存的使用
并發(fā)安全
降低項目的復雜度
便于比較復雜數(shù)據(jù),定制shouldComponentUpdate方便
時間旅行功能
函數(shù)式編程
Immutable缺點:
學習成本
庫的大?。ńㄗh使用seamless-immutable)
對現(xiàn)有項目入侵嚴重
容易與原生的對象進行混淆
2. 多個react組件性能優(yōu)化react組件在裝載過程中,react通過在render方法在內(nèi)存中產(chǎn)生一個樹形結(jié)構(gòu),樹上的節(jié)點代表一個react組件或者原生的Dom元素,這個樹形結(jié)構(gòu)就是我們所謂的Vitural Dom,react根據(jù)這個來渲染產(chǎn)生瀏覽器的Dom樹。
react在更新階段對比原有的Vitural Dom和新生成的Vitural Dom,找出不同之處,在根據(jù)不同來渲染Dom樹。
react為了追求高性能,采用了時間復雜度為O(N)來比較兩個屬性結(jié)構(gòu)的區(qū)別,因為要確切比較兩個樹形結(jié)構(gòu),需要通過O(N^3),這會降低性能。
節(jié)點類型不同
// A組件// B組件我們想把A組件更新成B組件,react在做比較的時候,發(fā)現(xiàn)最外面的根結(jié)點完全不一樣,直接銷毀之前的
節(jié)點,包括里面的子節(jié)點也一并銷毀,這是一個巨大的浪費,但是為了避免O(N^3)的時間復雜度,只能采用這種方式。所以在開發(fā)過程中,我們應該盡量避免上面的情況,不要將包裹節(jié)點的類型隨意改變。
兩個節(jié)點類型一樣
這里包括兩種情況,一種是節(jié)點是Dom類型,還有一種react組件。
對于dom類型,我們舉個例子:
// A組件Hello World!!!// B組件Good Bye!!!上述A和B組件的區(qū)別是文字、className、style中的color發(fā)生改變,因為Dom元素沒變,React只會修改他變化的部分。
針對react組件類型,渲染無非就是再執(zhí)行一遍組件實例的更新過程,最主要的就是定制shouldComponentUpdate。
多個子組件情況
例子一:
// A// B
從A變到B,如果shouldComponentUpdate處理得當,我們只需要更新裝載third的那一次就行。
我們來看看下一個例子:
// A// B
這里因為react是采用O(n)的時間復雜度,所以會依次將text為First的改為Zero,text為Second改為First,在最后再加上一個組件,text為Second?,F(xiàn)存的兩個的text的屬性都被改變了,所以會依次渲染。
如果我們這里有100個實例,那么就會發(fā)生100次更新。
這里我們就要用到Key了
簡單來說,其實這一個Key就是react組件的身份證號。
我們將上一個例子改成如下,就可以避免上面的問題了,react就能夠知道其實B里面的第二個和第三個組件其實就是A中的第一個和第二個實例。
// A// B
不過現(xiàn)在,react也會提醒我們不要忘記使用key,如果沒有加,瀏覽器中會報錯。
關(guān)于key的使用我們要注意的是,這個key值要穩(wěn)定不變的,就如同身份證號對于我們是穩(wěn)定不變的一樣。
一個常見的錯誤就是,拿數(shù)組的的下標值去當做key,這個是很危險的,代碼如下,我們一定要避免
{ todos.map((item, index) => {
}) } 未完待續(xù)...
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/105573.html
摘要:發(fā)布是由團隊開源的,操作接口庫,已成為事實上的瀏覽器操作標準。本周正式發(fā)布,為我們帶來了,,支持自定義頭部與腳部,支持增強,兼容原生協(xié)議等特性變化。新特性介紹日前發(fā)布了大版本更新,引入了一系列的新特性與提升,本文即是對這些變化進行深入解讀。 showImg(https://segmentfault.com/img/remote/1460000012940044); 前端每周清單專注前端...
摘要:工程實踐立足實踐,提示實際水平內(nèi)聯(lián)函數(shù)與性能很多關(guān)于性能優(yōu)化的文章都會談及內(nèi)聯(lián)函數(shù),其也是常見的被詬病為拖慢性能表現(xiàn)的元兇之一不過本文卻是打破砂鍋問到底,論證了內(nèi)聯(lián)函數(shù)并不一定就會拖慢性能,過度的性能優(yōu)化反而會有損于應用性能。 showImg(https://segmentfault.com/img/remote/1460000011481413?w=1240&h=825); 前端每周...
摘要:感謝王下邀月熊分享的前端每周清單,為方便大家閱讀,特整理一份索引。王下邀月熊大大也于年月日整理了自己的前端每周清單系列,并以年月為單位進行分類,具體內(nèi)容看這里前端每周清單年度總結(jié)與盤點。 感謝 王下邀月熊_Chevalier 分享的前端每周清單,為方便大家閱讀,特整理一份索引。 王下邀月熊大大也于 2018 年 3 月 31 日整理了自己的前端每周清單系列,并以年/月為單位進行分類,具...
摘要:的網(wǎng)站仍然使用有漏洞庫上周發(fā)布了開源社區(qū)安全現(xiàn)狀報告,發(fā)現(xiàn)隨著開源社區(qū)的日漸活躍,開源代碼中包含的安全漏洞以及影響的范圍也在不斷擴大。與應用安全是流行的服務(wù)端框架,本文即是介紹如何使用以及其他的框架來增強應用的安全性。 showImg(https://segmentfault.com/img/remote/1460000012181337?w=1240&h=826); 前端每周清單專注...
閱讀 1860·2021-11-15 11:39
閱讀 1225·2021-10-18 13:29
閱讀 1186·2021-08-31 09:42
閱讀 2740·2019-08-30 11:11
閱讀 2115·2019-08-26 12:12
閱讀 2114·2019-08-26 10:17
閱讀 3390·2019-08-23 18:38
閱讀 3228·2019-08-23 18:38