摘要:如何修復(fù)既然是不需要渲染,那就要阻止它的渲染。我個人覺得,在實際中,用跟兩個工具已經(jīng)可以很好幫我們判斷哪部分不需要重新渲染,幫助我們做出優(yōu)化。
背景
上一篇文章的結(jié)尾
http://imweb.io/topic/5985cc4...
我們說到,也許,不是所有的節(jié)點都需要重新渲染,對于那些不需要渲染的節(jié)點,我們?nèi)绾握业剿鼈儾⒆鰞?yōu)化呢?
本篇文章來具體解答這個問題。
應(yīng)用分析首先,先看這個應(yīng)用:頁面的兩部分分別渲染5000個節(jié)點,從1-5000。當(dāng)點擊按鈕之后,第二部分的節(jié)點會更新,重新渲染從2-5001的數(shù)字,但是第一部分保持不變。
import React, { createElement, Component } from "react"; import {render} from "react-dom"; import Perf from "react-addons-perf"; import ListItem from "./ListItem" function arrayGenerator(length) { return Array.apply(null, { length: length }).map(Number.call, Number) } class App extends Component { constructor(props) { super(props) this.state = { multiplier: 1 } } resetMultiplier() { this.setState({ multiplier: 2 }) } render() { return (); } } render({ arrayGenerator(5000).map(i => { return
}) } { arrayGenerator(5000).map(i => { return }) } ,document.getElementById("main"));
gitbug 鏈接:
https://github.com/hhhuangqio...
感興趣的同學(xué)可以下載跑一跑代碼
分析更新時間這里用react的Perf工具來測量重新渲染的時間。
使用方法:
npm install --save-dev react-addons-perf import Perf from "react-addons-perf"
這里主要用到四個方法:
Perf.start():開始計時
Perf.stop():結(jié)束計時
Perf.printInclusive():打印組件總的渲染時間
Perf.printWasted():打印浪費的時間
當(dāng)我們點擊按鈕,可以看到控制臺打印出下面的信息:
由控制臺的數(shù)據(jù)可以看出,App用了90.59ms渲染,其中渲染ListItem的時間為55ms,渲染了10000次,其中有5000次是浪費的,因為這部分頁面的內(nèi)容完全沒有更新的改動。
如何修復(fù)既然是不需要渲染,那就要阻止它的渲染。React給我們提供了一個方法shouldComponentUpdate(),當(dāng)這個方法返回true的時候,需要重新渲染,false的時候不需要(默認是true).
在這個栗子中,只要text的值不變,就不需要重新渲染。所以,可以這樣改寫ListItem 的shouldComponentUpdate
import React, { Component } from "react" export default class ListItem extends Component { shouldComponentUpdate(nextProps, nextState) { return nextProps.text !== this.props.text } render() { let { text } = this.props return
在重新點擊一下按鈕,在控制臺可以發(fā)現(xiàn)
App總的渲染時間降到了62.14ms,并且ListItem只重新渲染了5000個節(jié)點,完全消除了浪費的渲染。
對于上面的寫法,React提供了一個新的組件PureComponent來做這件事,它會自動淺對比props/state,當(dāng)兩者相同的時候不渲染節(jié)點。所以,listItem又可以改寫成
import React, { PureComponent } from "react" export default class ListItem extends PureComponent { render() { let { text } = this.props return
跑一跑代碼
通過控制臺可以看到達到的效果是一樣的(有點誤差是正常的)。
這里再安利一個可以發(fā)現(xiàn)應(yīng)用里是否存在不該重新渲染的節(jié)點工具:why-did-you-update
使用方法1、npm i --save-dev why-did-you-update 2、 import React from "react" if (process.env.NODE_ENV !== "production") { const {whyDidYouUpdate} = require("why-did-you-update") whyDidYouUpdate(React) }
然后點擊按鈕看控制臺
可以看到Value did not change. Avoidable re-render!的警告,是不是很實用!
PureComponent只會淺比較,所以不適合用于深層嵌套的對象。同時,PureComponent不僅僅會跳過自己的重新渲染,還會跳過它所有子節(jié)點的,所以要注意,用它的時候是最好沒有子節(jié)點并且不依賴于global state的展示型組件。
與Staleless的關(guān)系不知道有沒有人跟我有這樣的疑問,無狀態(tài)組件跟純凈組件有什么不同?這里做一個區(qū)分:
無狀態(tài)組件只是作為一個展示組件,它的好處是:
易復(fù)用,易測試
與邏輯處理數(shù)據(jù)解耦,一般來說,app里有越多無狀態(tài)組件越好,這說明邏輯處理都在上層,例如redux 中處理,這樣可以在不渲染的前提下,測數(shù)據(jù)邏輯。
壞處:
沒有生命周期,沒辦法用shouldComponentUpdate阻止重新渲染,這也就是說,它沒有幫助我們提高性能的作用,這也是它跟PureComponent最大的不同。
關(guān)于如何在實際中使用這兩個組件,還要根據(jù)具體的實際情況來選擇~
總結(jié)綜上可以看出,減少不必要的重新渲染對于提升我們的性能有很大的意義。我個人覺得,在實際中,用Perf跟why-did-you-update兩個工具已經(jīng)可以很好幫我們判斷哪部分不需要重新渲染,幫助我們做出優(yōu)化。
遺留點PureComponent那么好用,但是使用PureComponent是有條件的呀~
由于PureComponent只是做了一個淺比較,所以深層嵌套的對象跟數(shù)組都是比不出來的,可能會導(dǎo)致需要渲染的地方?jīng)]有重新渲染的錯誤展示。
那么淺比較又是什么呢?下篇文章我們來繼續(xù)探索
參考鏈接:
1、https://60devs.com/pure-compo...
2、https://engineering.musefind....
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://www.ezyhdfw.cn/yun/84777.html
摘要:事件系統(tǒng)合成事件的綁定方式合成事件的實現(xiàn)機制事件委派和自動綁定。高階組件如果已經(jīng)理解高階函數(shù),那么理解高階組件也很容易的。例如我們常見的方法等都是高階函數(shù)。對測試群眾來說,從質(zhì)量保證的角度出發(fā),單元測試覆蓋率是 事件系統(tǒng) 合成事件的綁定方式 `Test` 合成事件的實現(xiàn)機制:事件委派和自動綁定。 React合成事件系統(tǒng)的委托機制,在合成事件內(nèi)部僅僅是對最外層的容器進行了綁定,并且依賴...
摘要:對此沒有任何限制,它不關(guān)心這個。一種控制變化的辦法是不可改變的,持久化的數(shù)據(jù)結(jié)構(gòu)??偨Y(jié)檢測變化時開發(fā)中的核心問題,而框架們以各種方式解決這個問題。因為組件內(nèi)的變化是不被允許的。 AngularJS:臟檢查 我不知道什么更新了,所以當(dāng)更新的時候,我只能檢查所有的東西。 AngularJS 類似于 Ember,當(dāng)狀態(tài)改變的時候,必須人工去處理。但不同的是,AngularJS 從不同的角度來...
摘要:原方式中是經(jīng)過壓縮的腳本文件,預(yù)編譯后則是二進制文件。兩者影響疊加導(dǎo)致整體減小,包大小得到優(yōu)化。引擎包引擎包官方文檔中對內(nèi)存區(qū)的描述您的應(yīng)用用于處理代碼和資源如字節(jié)碼已優(yōu)化或已編譯的碼庫和字體的內(nèi)存。本文首發(fā)自普惠出行產(chǎn)品技術(shù) 自從 Google 的 Flutter 發(fā)布之后,F(xiàn)acebook 對 React-Native 的迭代開始快了起來,優(yōu)化 React-Native 的性能表現(xiàn)...
摘要:表示調(diào)用棧在下一將要執(zhí)行的任務(wù)。兩方性能解藥我們一般有兩種方案突破上文提到的瓶頸將耗時高成本高易阻塞的長任務(wù)切片,分成子任務(wù),并異步執(zhí)行這樣一來,這些子任務(wù)會在不同的周期執(zhí)行,進而主線程就可以在子任務(wù)間隙當(dāng)中執(zhí)行更新操作。 showImg(https://segmentfault.com/img/remote/1460000016008111); 性能一直以來是前端開發(fā)中非常重要的話題...
閱讀 3745·2021-09-22 15:28
閱讀 1359·2021-09-03 10:35
閱讀 943·2021-09-02 15:21
閱讀 3544·2019-08-30 15:53
閱讀 3547·2019-08-29 17:25
閱讀 630·2019-08-29 13:22
閱讀 1612·2019-08-28 18:15
閱讀 2351·2019-08-26 13:57