日日操夜夜添-日日操影院-日日草夜夜操-日日干干-精品一区二区三区波多野结衣-精品一区二区三区高清免费不卡

公告:魔扣目錄網為廣大站長提供免費收錄網站服務,提交前請做好本站友鏈:【 網站目錄:http://www.ylptlb.cn 】, 免友鏈快審服務(50元/站),

點擊這里在線咨詢客服
新站提交
  • 網站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會員:747


深入淺出React.js 性能分析

 

 

作者 | Addy Osmani

譯者 | 許學文

策劃 | 蔡芳芳

轉發鏈接:https://mp.weixin.qq.com/s/ciIl4Cg9ZULDUY77Yuot0A

本文最初發布于Addy Osmani博客,經原作者授權由 InfoQ 中文站翻譯并分享

今天我將向大家演示如何使用 React Profiler APITracing API 以及 User Timing API 來分別追蹤 React 的組件渲染、用戶交互以及自定義性能指標。

React Profiler API

首先來了解下 React Profiler,它主要用來追蹤應用組件的 渲染過程 以及渲染開銷,同時標記出應用的性能瓶頸。Profiler 接受一個 onRender 回調函數,當被追蹤的組件以及子代組件發生更新時,該函數就會被調用。下圖是在影片排期應用中使用 Profiler 追蹤各個組件渲染:

深入淺出React.js 性能分析

 

Profiler 中 onRender 回調函數的具體參數如下:

  • id:: 這是 Profiler 的唯一標示,區分是哪個 Profiler 追蹤的組件樹發生了更新
  • phase: 如果更新是掛載階段這個值就是“mount”,如果是二次渲染階段就是“update”
  • act ualDuration: 更新花費的渲染時間
  • baseDuration: 更新預計花費的渲染時間
  • startTime: 更新開始時間點
  • commitTime: 更新提交的時間點
  • interactions: 更新中包含的交互信息

 

const callback = (id, phase, actualTime, baseTime, startTime, commitTime) => {
    console.log(`${id}'s ${phase} phase:`);
    console.log(`Actual time: ${actualTime}`);
    console.log(`Base time: ${baseTime}`);
    console.log(`Start time: ${startTime}`);
    console.log(`Commit time: ${commitTime}`);
}

運行上面的代碼,在 Chrome 調試器中可以看到如下輸出:

深入淺出React.js 性能分析

 

也可以打開 React DevTools,在 Profiler 面板中可以看到組件渲染的時間火焰圖:

深入淺出React.js 性能分析

 

切換到排序視圖

深入淺出React.js 性能分析

 

當然也可以使用多個 Profiler 來分別追蹤應用中的各個不同的部分,示例代碼如下:

import React, { Fragment, unstable_Profiler as Profiler} from "react";
render(
  <App>
    <Profiler id="Header" onRender={callback}>
      <Header {...props} />
    </Profiler>
    <Profiler id="Movies" onRender={callback}>
      <Movies {...props} />
    </Profiler>
  </App>
)

知道了如何追蹤組件渲染,那么如果想跟蹤交互,該怎么做

交互追蹤 Tracing API

想一下,如果能追蹤到交互(例如:按鈕的點擊),那么在回答“這個按鈕點擊花費了多少時間更新 DOM?”這樣的問題時是不是就有了依據。要感謝 Brian Vaughn 的努力,React 在其 調度包 中引入了對這個功能的試驗支持,更詳細的說明可以點擊 這里 查看。

一個交互追蹤,需要包含一個描述(例如:添加購物車按鈕被點擊)、一個時間戳和一個回調函數,在回調函數中你可以定義一些和該交互相關的邏輯。在“影片排期應用”中就有一個添加電影到播放列表的“+”號按鈕,這個就是一個交互按鈕。

深入淺出React.js 性能分析

 

下面的代碼演示了如何追蹤這個按鈕的點擊行為:

import { unstable_Profiler as Profiler } from "react";
import { render } from "react-dom";
import { unstable_trace as trace } from "scheduler/tracing";
class MyComponent extends Component {
  addMovieButtonClick = event => {
    trace("Add To Movies Queue click", performance.now(), () => {
      this.setState({ itemAddedToQueue: true });
    });
  };

在 React 開發調試工具的 interaction 面板中可以看到具體的交互行為和持續時間:

深入淺出React.js 性能分析

 

這個 API 同樣也可以 追蹤初始化渲染

import { unstable_trace as trace } from "scheduler/tracing";
trace("initial render", performance.now(), () => {
   ReactDom.render(<App />, document.getElementById("app"));
})
深入淺出React.js 性能分析

 

Brian 提供了更多的例子,比如如何追蹤異步行為等。這些示例都在其“React 中進行交互追蹤”項目的 gist 中。

Puppeteer 的使用

如果想對 UI 交互追蹤腳本做進一步了解的話,你可能會對 Puppeteer 這個庫感興趣。Puppeteer 是一個 Node 庫,基于 Chrome 開發協議封裝 API 來操作 headless Chrome(譯者注:Chrome 瀏覽器對無界面形態)。

為了捕獲 DevTools 對當前運行程序性能的追蹤,Puppeteer 提供了 trace .start() 和 trace.stop() 兩個 API,下面我們就用它來追蹤按鈕點擊的過程,代碼如下::

const puppeteer = require('puppeteer');
(async () => {
  const browser = await puppeteer.launch();
  const page = await browser.newPage();
  const navigationPromise = page.waitForNavigation();
  await page.goto('https://react-movies-queue.glitch.me/')
  await page.setViewport({ width: 1276, height: 689 });
  await navigationPromise;
  const addMovieToQueueBtn = 'li:nth-child(3) > .card > .card__info > div > .button';
  await page.waitForSelector(addMovieToQueueBtn);
  // 開始追蹤...
  await page.tracing.start({ path: 'profile.json' });
  // 按鈕點擊
  await page.click(addMovieToQueueBtn);
  // 停止追蹤
  await page.tracing.stop();
  await browser.close();

然后在開發工具的性能面板中導入 profile.json,我們就可以看到當按鈕點擊的時候,所有函數的調用情況:

深入淺出React.js 性能分析

 

如果你對交互追蹤感興趣并且想了解更多的話,不妨看看 Stoyan Stefanov 的“JAVAScript 組件級別的 CPU 開銷”這篇文章。

客戶端性能追蹤 API

使用 客戶端性能追蹤 API 可以追蹤一些定制的性能指標,并且時間精確度會更高。它有 2 個主要的 API:

  • window.performance.mark(): 存儲當前 mark 執行時的時間戳
  • window.performance.measure(): 存儲 2 個相同 mark 之間的執行時間

示例代碼如下:

// 記錄任務開始之前的時間戳
performance.mark('Movies:updateStart');
// 這里執行了一些任務...
// 記錄任務結束的時間戳
performance.mark('Movies:updateEnd');
// 計算任務開始前后的差值
performance.measure('moviesRender', 'Movies:updateStart', 'Movies:updateEnd'

當你通過 Chrome 調試工具中的性能面板查看一個 React 應用時,有一個“Timings”的區域,這里歸集了你的 React 組件的執行時間。在渲染時,React 會把通過客戶端 API 得到的性能數據發布到這里。

深入淺出React.js 性能分析

 

注意:React 在它的開發包中用 Profiler 替代了 User Timings,不過由于 User Timings 的時間精度更高,所以可能會在未來的 3 級規格的瀏覽器中重新添加它。

在互聯網上,你會發現有一些其他的 React 應用已經在使用 User Timing 追蹤他們的 自定義指標,包括 Reddit 網站中的“到第一標題可見花費的時間”和 Spotify 網站中的“到回放準備完畢花費的時間”。

深入淺出React.js 性能分析

 

還可以在 Chrome 調試器的 Lighthouse 面板 中查看到定制化的 User Timing 標記和追蹤方法,如下圖:

深入淺出React.js 性能分析

 

在 Next.js 的最近版本中也針對一些事件 添加 了很多 User timing 標記和追蹤,例如:

  • Next.js-hydration: 混合持續時間
  • Next.js-nav-to-render: 導航開始到開始渲染之間的時間

所有的這些追蹤都可以在調試器的 Timings 區域看到:

深入淺出React.js 性能分析

 

對比 DevTools 和 Lighthouse

值得注意的是,Lighthouse 和 Chrome 調試工具 中的性能面板都可以深入分析 React 應用程序的加載和運行時性能,用戶可以看到下面這些性能指標:

深入淺出React.js 性能分析

 

React 用戶可能會喜歡像 總阻塞時間 (TBT) 這樣的新指標,它量化一個頁面具體什么時候才可以交互(可 交互時間), 下面我們可以看下在并發模式前后應用發生更新時,TBT 的情況:

深入淺出React.js 性能分析

 

這些工具一般能幫助我們了解在瀏覽器級別的視圖性能瓶頸,例如,哪些 繁重冗長的任務 會引起交互延遲 (例如按鈕點擊響應) :

深入淺出React.js 性能分析

 

Lighthouse 還為一些特定的性能場景提供了修改建議。如在 Lighthouse 6.0 中可以看到一個提示,建議我們移除 未使用的 JavaScript代碼。Lighthouse 追蹤到了這個問題并且提醒我們可以使用 React.lazy () 來引入這個 JavaScript。

深入淺出React.js 性能分析

 

借助用戶端的硬件進行性能智能檢查,往往對性能分析非常有幫助。

最后,除了上面提到的我通常還會從 RUM 和 CrUX 獲取一些數據字段,然后用 webpagetest.org/easy 工具幫我生成更多的場景圖片,以便更好的進行性能分析。

分享到:
標簽:React js
用戶無頭像

網友整理

注冊時間:

網站:5 個   小程序:0 個  文章:12 篇

  • 51998

    網站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會員

趕快注冊賬號,推廣您的網站吧!
最新入駐小程序

數獨大挑戰2018-06-03

數獨一種數學游戲,玩家需要根據9

答題星2018-06-03

您可以通過答題星輕松地創建試卷

全階人生考試2018-06-03

各種考試題,題庫,初中,高中,大學四六

運動步數有氧達人2018-06-03

記錄運動步數,積累氧氣值。還可偷

每日養生app2018-06-03

每日養生,天天健康

體育訓練成績評定2018-06-03

通用課目體育訓練成績評定