日本综合一区二区|亚洲中文天堂综合|日韩欧美自拍一区|男女精品天堂一区|欧美自拍第6页亚洲成人精品一区|亚洲黄色天堂一区二区成人|超碰91偷拍第一页|日韩av夜夜嗨中文字幕|久久蜜综合视频官网|精美人妻一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問(wèn)題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營(yíng)銷解決方案
熱點(diǎn)技術(shù):React性能優(yōu)化總結(jié)

初學(xué)者對(duì)React可能滿懷期待,覺(jué)得React可能完爆其它一切框架,甚至不切實(shí)際地認(rèn)為React可能連原生的渲染都能完爆——對(duì)框架的狂熱確實(shí)會(huì)出現(xiàn)這樣的不切實(shí)際的期待。讓我們來(lái)看看React的官方是怎么說(shuō)的。React官方文檔在Advanced Performanec這一節(jié),這樣寫(xiě)道:

創(chuàng)新互聯(lián)專注于昭平企業(yè)網(wǎng)站建設(shè),響應(yīng)式網(wǎng)站,成都商城網(wǎng)站開(kāi)發(fā)。昭平網(wǎng)站建設(shè)公司,為昭平等地區(qū)提供建站服務(wù)。全流程定制網(wǎng)站制作,專業(yè)設(shè)計(jì),全程項(xiàng)目跟蹤,創(chuàng)新互聯(lián)專業(yè)和態(tài)度為您提供的服務(wù)

  
  
  1. One of the first questions people ask when considering React for a project is whether their application will be as fast and responsive as an equivalent non-React version 

顯然React自己也其實(shí)只是想盡量達(dá)到跟非React版本相若的性能,

你所不知道的render

react的組件渲染分為初始化渲染和更新渲染。在初始化渲染的時(shí)候會(huì)調(diào)用根組件下的所有組件的render方法進(jìn)行渲染,如下圖(綠色表示已渲染,這一層是沒(méi)有問(wèn)題的):

但是當(dāng)我們要更新某個(gè)子組件的時(shí)候,如下圖的綠色組件(從根組件傳遞下來(lái)應(yīng)用在綠色組件上的數(shù)據(jù)發(fā)生改變):

我們的理想狀態(tài)是只調(diào)用關(guān)鍵路徑上組件的render,如下圖:

但是react的默認(rèn)做法是調(diào)用所有組件的render,再對(duì)生成的虛擬DOM進(jìn)行對(duì)比,如不變則不進(jìn)行更新。這樣的render和虛擬DOM的對(duì)比明顯是在浪費(fèi),如下圖(黃色表示浪費(fèi)的render和虛擬DOM對(duì)比)

Tips:

  • 拆分組件是有利于復(fù)用和組件優(yōu)化的。

  • 生成虛擬DOM并進(jìn)行比對(duì)發(fā)生在render()后,而不是render()前。

更新階段的生命周期

  • componentWillReceiveProps(object nextProps):當(dāng)掛載的組件接收到新的props時(shí)被調(diào)用。此方法應(yīng)該被用于比較this.props 和 nextProps以用于使用this.setState()執(zhí)行狀態(tài)轉(zhuǎn)換。(組件內(nèi)部數(shù)據(jù)有變化,使用state,但是在更新階段又要在props改變的時(shí)候改變state,則在這個(gè)生命周期里面)

  • shouldComponentUpdate(object nextProps, object nextState): -boolean 當(dāng)組件決定任何改變是否要更新到DOM時(shí)被調(diào)用。作為一個(gè)優(yōu)化實(shí)現(xiàn)比較this.props 和 nextProps 、this.state 和 nextState ,如果React應(yīng)該跳過(guò)更新,返回false。

  • componentWillUpdate(object nextProps, object nextState):在更新發(fā)生前被立即調(diào)用。你不能在此調(diào)用this.setState()。

  • componentDidUpdate(object prevProps, object prevState): 在更新發(fā)生后被立即調(diào)用。(可以在DOM更新完之后,做一些收尾的工作)

Tips:

  • React的優(yōu)化是基于shouldComponentUpdate的,該生命周期默認(rèn)返回true,所以一旦prop或state有任何變化,都會(huì)引起重新render。

shouldComponentUpdate

react在每個(gè)組件生命周期更新的時(shí)候都會(huì)調(diào)用一個(gè)shouldComponentUpdate(nextProps, nextState)函數(shù)。它的職責(zé)就是返回true或false,true表示需要更新,false表示不需要,默認(rèn)返回為true,即便你沒(méi)有顯示地定義 shouldComponentUpdate 函數(shù)。這就不難解釋上面發(fā)生的資源浪費(fèi)了。

為了進(jìn)一步說(shuō)明問(wèn)題,我們?cè)僖靡粡埞倬W(wǎng)的圖來(lái)解釋,如下圖( SCU表示shouldComponentUpdate,綠色表示返回true(需要更新),紅色表示返回false(不需要更新);vDOMEq表示虛擬DOM比對(duì),綠色表示一致(不需要更新),紅色表示發(fā)生改變(需要更新)):

根據(jù)渲染流程,首先會(huì)判斷shouldComponentUpdate(SCU)是否需要更新。如果需要更新,則調(diào)用組件的render生成新的虛擬DOM,然后再與舊的虛擬DOM對(duì)比(vDOMEq),如果對(duì)比一致就不更新,如果對(duì)比不同,則根據(jù)最小粒度改變?nèi)ジ翫OM;如果SCU不需要更新,則直接保持不變,同時(shí)其子元素也保持不變。

  • C1根節(jié)點(diǎn),綠色SCU (true),表示需要更新,然后vDOMEq紅色,表示虛擬DOM不一致,需要更新。

  • C2節(jié)點(diǎn),紅色SCU (false),表示不需要更新,所以C4,C5均不再進(jìn)行檢查

  • C3節(jié)點(diǎn)同C1,需要更新

  • C6節(jié)點(diǎn),綠色SCU (true),表示需要更新,然后vDOMEq紅色,表示虛擬DOM不一致,更新DOM。

  • C7節(jié)點(diǎn)同C2

  • C8節(jié)點(diǎn),綠色SCU (true),表示需要更新,然后vDOMEq綠色,表示虛擬DOM一致,不更新DOM。

帶坑的寫(xiě)法:

  • {…this.props} (不要濫用,請(qǐng)只傳遞component需要的props,傳得太多,或者層次傳得太深,都會(huì)加重shouldComponentUpdate里面的數(shù)據(jù)比較負(fù)擔(dān),因此,也請(qǐng)慎用spread attributes())。

  • ::this.handleChange()。(請(qǐng)將方法的bind一律置于constructor)

  • this.handleChange.bind(this,id)

  • 復(fù)雜的頁(yè)面不要在一個(gè)組件里面寫(xiě)完。

  • 請(qǐng)盡量使用const element。

  • map里面添加key,并且key不要使用index(可變的)。具體可參考使用Perf工具研究React Key對(duì)渲染的影響

  • 盡量少用setTimeOut或不可控的refs、DOM操作。

  • 數(shù)據(jù)盡可能簡(jiǎn)單明了,扁平化。

性能檢測(cè)工具

React官方提供的:React.addons.Perf

react官方提供一個(gè)插件React.addons.Perf可以幫助我們分析組件的性能,以確定是否需要優(yōu)化。
打開(kāi)console面板,先輸入Perf.start()執(zhí)行一些組件操作,引起數(shù)據(jù)變動(dòng),組件更新,然后輸入Perf.stop()。(建議一次只執(zhí)行一個(gè)操作,好進(jìn)行分析)
再輸入Perf.printInclusive查看所有涉及到的組件render,如下圖(官方圖片):

或者輸入Perf.printWasted()查看下不需要的的浪費(fèi)組件render,如下圖(官方圖片):

優(yōu)化前:

優(yōu)化后:

其他的檢測(cè)工具

react-perf-tool為React應(yīng)用提供了一種可視化的性能檢測(cè)方案,該工程同樣是基于React.addons,但是使用圖表來(lái)顯示結(jié)果,更加方便。

React官方的解決方案

PureRenderMixin(es5)

 
 
  1. var PureRenderMixin = require('react-addons-pure-render-mixin'); 
  2. React.createClass({ 
  3.   mixins: [PureRenderMixin], 
  4.  
  5.   render: function() { 
  6.     return foo
  •   } 
  • }); 
  • Shallow Compare (es6)

     
     
    1. var shallowCompare = require('react-addons-shallow-compare'); 
    2. export class SampleComponent extends React.Component { 
    3.   shouldComponentUpdate(nextProps, nextState) { 
    4.     return shallowCompare(this, nextProps, nextState); 
    5.   } 
    6.  
    7.   render() { 
    8.     return foo
  •   } 
  • es7裝飾器的寫(xiě)法:

     
     
    1. import pureRender from "pure-render-decorator" ... @pureRender class Person extends Component { render() { console.log("我re-render了"); const {name,age} = this.props; return ( 
       姓名: {name}  age: {age} 
       
    2.       ) 
    3.   } 

    pureRender很簡(jiǎn)單,就是把傳進(jìn)來(lái)的component的shouldComponentUpdate給重寫(xiě)掉了,原來(lái)的shouldComponentUpdate,無(wú)論怎樣都是return ture,現(xiàn)在不了,我要用shallowCompare比一比,shallowCompare代碼及其簡(jiǎn)單,如下:

     
     
    1. function shallowCompare(instance, nextProps, nextState) { 
    2.   return !shallowEqual(instance.props, nextProps) || !shallowEqual(instance.state, nextState); 

    缺點(diǎn)

    shallowEqual其實(shí)只比較props的第一層子屬性是不是相同,就像上述代碼,props 是如下

     
     
    1.   detail: { 
    2.     name: "123", age: "123" 
    3.   } 

    他只會(huì)比較props.detail ===nextProps.detail,導(dǎo)致在傳入復(fù)雜的數(shù)據(jù)的情況下,優(yōu)化失效。

    immutable.js

    我們也可以在 shouldComponentUpdate() 中使用使用 deepCopy 和 deepCompare 來(lái)避免無(wú)必要的 render(),但 deepCopy 和 deepCompare 一般都是非常耗性能的。

    Immutable Data 就是一旦創(chuàng)建,就不能再被更改的數(shù)據(jù)。對(duì) Immutable 對(duì)象的任何修改或添加刪除操作都會(huì)返回一個(gè)新的 Immutable 對(duì)象。

    Immutable 實(shí)現(xiàn)的原理是 Persistent Data Structure(持久化數(shù)據(jù)結(jié)構(gòu)),也就是使用舊數(shù)據(jù)創(chuàng)建新數(shù)據(jù)時(shí),要保證舊數(shù)據(jù)同時(shí)可用且不變。同時(shí)為了避免 deepCopy 把所有節(jié)點(diǎn)都復(fù)制一遍帶來(lái)的性能損耗,Immutable 使用了 Structural Sharing(結(jié)構(gòu)共享),即如果對(duì)象樹(shù)中一個(gè)節(jié)點(diǎn)發(fā)生變化,只修改這個(gè)節(jié)點(diǎn)和受它影響的父節(jié)點(diǎn),其它節(jié)點(diǎn)則進(jìn)行共享。請(qǐng)看下面動(dòng)畫(huà):

    Immutable 則提供了簡(jiǎn)潔高效的判斷數(shù)據(jù)是否變化的方法,只需 === 和 is 比較就能知道是否需要執(zhí)行 render(),而這個(gè)操作幾乎 0 成本,所以可以極大提高性能。修改后的 shouldComponentUpdate 是這樣的:

     
     
    1. import { is } from 'immutable'; 
    2.  
    3. shouldComponentUpdate: (nextProps = {}, nextState = {}) => { 
    4.   const thisProps = this.props || {}, thisState = this.state || {}; 
    5.  
    6.   if (Object.keys(thisProps).length !== Object.keys(nextProps).length || 
    7.       Object.keys(thisState).length !== Object.keys(nextState).length) { 
    8.     return true; 
    9.   } 
    10.  
    11.   for (const key in nextProps) { 
    12.     if (!is(thisProps[key], nextProps[key])) { 
    13.       return true; 
    14.     } 
    15.   } 
    16.  
    17.   for (const key in nextState) { 
    18.     if (thisState[key] !== nextState[key] || !is(thisState[key], nextState[key])) { 
    19.       return true; 
    20.     } 
    21.   } 
    22.   return false; 
    23.  
    24. react-immutable-render-mixin 

    這是一個(gè)facebook/immutable-js的react pure render mixin 的庫(kù),可以簡(jiǎn)化很多寫(xiě)法。
    使用react-immutable-render-mixin可以實(shí)現(xiàn)裝飾器的寫(xiě)法。

     
     
    1. import React from 'react'; 
    2. import { immutableRenderDecorator } from 'react-immutable-render-mixin'; 
    3.  
    4. @immutableRenderDecorator 
    5. class Test extends React.Component { 
    6.   render() { 
    7.     return 
    8.   } 

    Immutable 詳解及 React 中實(shí)踐

    無(wú)狀態(tài)組件

    為了避免一定程度的浪費(fèi),react官方還在0.14版本中加入了無(wú)狀態(tài)組件,如下:

     
     
    1. // es6 
    2. const HelloMessage = (props) => 
      Hello {props.name}

    高階組件(接下來(lái)的方向)

    大部分使用mixin和class extends的地方,高階組件都是更好的方案——畢竟組合優(yōu)于繼承。

    參考文章

    使用ES6編寫(xiě)React應(yīng)用(4):使用高階組件替代Mixins
    Mixin 已死,Composition 萬(wàn)歲

    React同構(gòu)直出(接下來(lái)方向)

    同構(gòu)基于服務(wù)端渲染,卻不止是服務(wù)端渲染。

    React在減少重復(fù)渲染方面確實(shí)是有一套獨(dú)特的處理辦法,那就是virtual DOM,但顯示在首次渲染的時(shí)候React絕無(wú)可能超越原生的速度。因此,我們?cè)谧鰞?yōu)化的時(shí)候,接下來(lái)可以做的事情就是:

    首屏?xí)r間可能會(huì)比較原生的慢一些,但可以嘗試用React Server Render (又稱Isomorphic)去提高效率


    文章題目:熱點(diǎn)技術(shù):React性能優(yōu)化總結(jié)
    文章起源:http://www.dlmjj.cn/article/djdcpec.html