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