[譯] 高性能 React:3 個新工具加速你的應用

一般來講 React 是至關快的,但開發者也很容易犯一些錯誤致使出現性能問題。組件掛載過慢、組件樹過深和一些非必要的渲染週期能夠迅速地聯手拉低你的應用速度。前端

幸運的是有大量的工具,甚至有些是 React 內置的,能夠幫助咱們檢測性能問題。本文將着重介紹一些加快 React 應用的工具和技術。每一部分都配有一個可交互並且(但願是)有趣的 demo!react

工具 #1: 性能時間軸

React 15.4.0 引入了一個新的性能時間軸特性,能夠精確展現組件什麼時候掛載、更新和卸載。也可讓你可視化地觀察組件生命週期相互之間的關係。android

注意: 目前,這一特性僅支持 Chrome、Edge 和 IE,由於它調用的 User Timing API 尚未在全部瀏覽器中實現。ios

如何使用

  1. 打開你的應用並追加一個參數:react_perf。例如, http://localhost:3000?react_perf
  2. 打開 Chrome 開發者工具 Performance 欄並點擊 Record
  3. 執行你想要分析的操做。
  4. 中止記錄。
  5. 觀察 User Timing 選項下的可視化視圖。

理解輸出結果

每個色條顯示的是一個組件作「處理」的時間。因爲 JavaScript 是單線程的,每當一個組件正在掛載或渲染,它都會霸佔主線程,並阻塞其餘代碼運行。git

[update] 這樣中括號內的文字描述的是生命週期的哪個階段正在發生。把時間軸按照步驟分解,你能夠看到依據方法的細粒度的計時,好比 [componentDidMount] [componentWillReceiveProps] [ctor] (constructor) 和 [render]github

堆疊的色條表明組件樹,雖然在 React 擁有過深的組件樹也比較典型,但若是你想優化一個頻繁掛載的組件,減小嵌套組件的數量也是有幫助的,由於每一層都會增長少許的性能和內存消耗。web

這裏須要注意的是時間軸中的計時時長是針對 React 的開發環境構建的,會比生產環境慢不少。實際上性能時間軸自己也會拖慢你的應用。雖然這些時長不能表明真正的性能指標,但不一樣組件間的相對時間是精確的。並且一個組件是否徹底被更新不取決因而否是生產環境的構建。npm

Demo #1

出於樂趣,我故意寫了一個具備嚴重性能問題的 TodoMVC 應用。你能夠在這裏嘗試後端

打開 Chrome 開發者工具,切換到 「Performance」 欄,點擊 Record 開始記錄時間軸。而後在應用中添加一些 TODO,中止記錄,檢查時間軸。看看你能不能找出形成性能問題的組件 :)瀏覽器

Tool #2: why-did-you-update

在 React 中最影響性能的問題之一就是非必要的渲染週期。默認狀況下,一旦父組件渲染,React 組件就會跟着從新渲染,即便它們的 props 沒有變化也是如此。

舉個例子,若是我有一個簡單的組件長這樣:

class DumbComponent extends Component {
  render() {
    return <div> {this.props.value} </div>;
  }
}複製代碼

它的父組件是這樣:

class Parent extends Component {
  render() {
    return <div>
      <DumbComponent value={3} />
    </div>;
  }
}複製代碼

每當父組件渲染,DumbComponent 就會從新渲染,儘管它的 props 沒有改變。

通常來說,若是 render 運行,而且虛擬 DOM 沒有改變,並且既然 render 應該是個純淨的沒有任何反作用的方法,那麼這就是一個沒必要要的渲染週期。在一個大型應用中檢測這種事情是很是困難的,但幸運的是有一個工具能夠幫得上忙。

使用 why-did-you-update

why-did-you-update 是一個 React 鉤子工具,用來檢測潛在的非必要組件渲染。它會檢測到被調用但 props 沒有改變的組件 render

安裝

  1. 使用 npm 安裝: 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)
    }

注意: 這個工具在本地開發環境使用起來很是棒,可是要確保生產環境要禁用掉,由於它會拖慢你的應用。

理解輸出結果

why-did-you-update 在運行時監聽你的應用,並用日誌輸出可能存在非必要更新的組件。它讓你看到一個渲染週期先後的 props 對比,來決定是否可能存在非必要的更新。

Demo #2

爲了演示 why-did-you-update,我在 TodoMVC 中安裝了這個庫並放在 Code Sandbox 網站上,這是一個在線的 React 練習場。 打開瀏覽器控制檯,並添加一些 TODO 來查看輸出。

這裏查看 demo

注意這個應用中不多的組件存在非必要渲染。嘗試執行上述的技術來避免非必要渲染,若是操做正確,why-did-you-update 不會在控制檯輸出任何內容。

Tool #3: React Developer Tools

React Developer Tools 這個 Chrome 擴展有一個內置特性用來可視化組件更新。這有助於防止非必要的渲染週期。使用它,首先要確保在這裏安裝了這個擴展

而後點擊 Chrome 開發者工具中的 「React」 選項卡打開擴展並勾選「Highlight Updates」。

而後簡單操做你的應用。和不一樣的組件交互並觀察 DevTools 施展它的魔法。

理解輸出結果

React Developer Tools 在給定的時間點高亮正在從新渲染的組件。根據更新的頻率,使用不一樣的顏色。藍色顯示罕見更新,通過綠色、黃色的過渡,一直到紅色用來顯示更新頻繁的組件。

看到黃色或紅色並不必要以爲必定是壞事。它可能發生在調整一個滑塊或頻繁觸發更新的其餘 UI 元素,這屬於意料之中。但若是當你點擊一個簡單的按鈕而且看到了紅色這可能就意味着事情不對了。這個工具的目的就是識破正在發生非必要更新的組件。做爲應用的開發者,你應該對給定時間內哪一個組件應該被更新有一個大致的概念。

Demo #3

爲了演示高亮,我故意讓 TodoMVC 應用更新一些非必要的組件。

這裏查看 demo

打開上面的連接,而後打開 React Developer Tools 並啓用更新高亮。當你在上面的文字輸入框中輸入內容時,你將看到全部的 TODO 非必要地高亮。你輸入得越快,你會看到顏色變化指示更新愈來愈頻繁。

修復非必要渲染

一旦你已經肯定應用中非必要從新渲染的組件,有幾種簡單的方法來修復。

使用 PureComponent

在上面的例子中,DumbComponent 是隻接收屬性的純函數。這樣,組件就只有當它的 props 變化的時候才從新渲染。React 有一個特殊的內置組件類型叫作 PureComponent,就是適用這種狀況的用例。

與繼承自 React.Component 相反,像這樣使用 React.PureComponent:

class DumbComponent extends PureComponent {
  render() {
    return <div> {this.props.value} </div>;
  }
}複製代碼

那麼只有當這個組件的 props 實際發生變化時它纔會被從新渲染了。就是這樣!

注意 PureComponent 對 props 作了一個淺對比,所以若是你使用複雜的數據結構,它可能會錯失一些屬性變化而不會更新你的組件。

調用 shouldComponentUpdate

shouldComponentUpdate 是一個在 render 以前 propsstate 發生改變時被調用的組件方法。若是 shouldComponentUpdate 返回 true,render 將會被調用,若是返回 false 什麼也不會發生。

經過執行這個方法,你能夠命令 React 在 props 沒有發生改變的時候避免給定組件的從新渲染。

例如,咱們能夠在上文中的 DumbComponent 中這樣調用 shouldComponentUpdate

class DumbComponent extends Component {
  shouldComponentUpdate(nextProps) {
    if (this.props.value !== nextProps.value) {
      return true;
    } else {
      return false;
    }
  }

render() {
    return <div>foo</div>;
  }
}複製代碼

在生產環境中調試性能問題

React Developer Tools 只能在你本身的機器上運行的應用中使用。若是您有興趣瞭解用戶在生產中看到的性能問題,試試 LogRocket

LogRocket 就像是 web 應用的 DVR,會記錄發生在你的站點上的全部的一切。你能夠重現帶有 bug 或性能問題的會話來快速瞭解問題的根源,而不用猜想問題發生的緣由。

LogRocket 工具爲你的應用記錄性能數據、Redux actions/state、日誌、帶有請求頭和請求體的網絡請求和響應以及瀏覽器的元數據。它也能記錄頁面上的 HTML 和 CSS,甚至能夠爲最複雜的單頁面應用從新建立完美像素的視頻。

LogRocket | 爲 JavaScript 應用而生的日誌記錄和會話回放工具
LogRocket 幫助你瞭解用影響你用戶的問題,這樣你就能夠回過頭來構建偉大的軟件了。
logrocket.com


感謝閱讀,但願這些工具和技術能在你的下一個 React 項目中幫到你!


掘金翻譯計劃 是一個翻譯優質互聯網技術文章的社區,文章來源爲 掘金 上的英文分享文章。內容覆蓋 AndroidiOSReact前端後端產品設計 等領域,想要查看更多優質譯文請持續關注 掘金翻譯計劃

相關文章
相關標籤/搜索