反应应用程序性能分析

今天,我们将讨论使用React Profiler API测量渲染React组件的性能。我们还将使用新的实验性Interaction Tracing API评估与组件的交互。此外,我们将使用用户计时API进行自己的测量。

我们将使用React Movies Queue应用程序作为实验平台。


反应电影队列应用程序

React Profiler API


React Profiler API旨在衡量渲染性能并帮助识别应用程序性能瓶颈。

import React, { Fragment, unstable_Profiler as Profiler} from "react";

该组件Profiler接受回调onRender作为属性。每次在分析树中的组件提交更新时都会调用它。

const Movies = ({ movies, addToQueue }) => (
  <Fragment>
    <Profiler id="Movies" onRender={callback}>

为了测试目的,让我们尝试测量渲染组件零件所需的时间Movies这是它的外观。


使用React开发人员

回调工具的React Movies Queue应用程序和Movies研究onRender接受接受参数,这些参数描述了正在渲染的内容以及渲染所需的时间。这包括以下内容:

  • idid来自Profiler更改提交的组件树的属性
  • phase:或mount(如果已安装树),或update(如果树已重新渲染)。
  • actualDuration:呈现固定更新所花费的时间。
  • baseDuration:估计的时间来呈现整个子树而不进行缓存。
  • startTime:React开始呈现此更新的时间。
  • commitTime:React提交此更新的时间。
  • 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开发人员工具,转到书签,Profiler并可视化有关组件渲染时间的信息。下面是火焰图形式的可视化视图。


在React Developer Tools中使用概要分析结果,

我也喜欢在这里使用视图模式Ranked,它提供了数据的有序视图。因此,花费最多时间渲染的组件位于列表的顶部。


在排名模式下查看性能分析结果

此外,您可以使用多个组件在应用程序的不同部分进行测量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>
);

以及如何分析用户与组件的交互?

互动追踪API


能够跟踪用户与应用程序界面的交互(例如对项目的点击)将是很好的。这将使您能够找到有趣的问题的答案,例如:“单击此按钮后,更新DOM需要多长时间?”。幸运的是,React提供了实验性支持,可使用新调度程序包中的Interaction Tracing API分析用户与应用程序的交互您可以在此处阅读有关文档

有关用户和应用程序之间交互的信息将附带说明(例如,“用户单击了添加到购物车”按钮)和时间戳。另外,在设置交互分析时,使用回调来执行与一个或另一个交互相对应的动作。

在我们的应用程序中,有一个Add Movie To Queue显示图标的按钮+它用于将电影添加到观看队列。


用于将影片添加到观看队列的按钮

这是一个代码示例,用于监视此用户与应用程序交互的状态更新:

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 Tracing API,您还可以收集有关第一个组件渲染的信息:

import { unstable_trace as trace } from "scheduler/tracing";

trace("initial render", performance.now(), () => {
   ReactDom.render(<App />, document.getElementById("app"));
});



组件首次渲染的分析

API作者提供其用法的其他示例例如,说明异步任务的概要分析。

木偶戏


为了自动化测试用户与应用程序元素的交互,使用Puppeteer似乎很有趣这是一个Node.js库,它提供对高级API的访问,该API设计为无需使用DevTools协议的用户界面即可控制Chrome浏览器。

使用Puppeteer时,会为开发人员提供帮助方法, tracing.start()tracing.stop()用于收集DevTools性能指标。以下是使用这些机制收集有关您单击我们感兴趣的按钮时发生的情况的数据的示例。

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.jsonPerformance开发人员的工具栏中后,我们可以看到单击按钮触发了哪些函数调用。


单击按钮后果的分析

如果您对组件性能分析的主题感兴趣,请阅读材料。

用户计时API


用户计时API允许开发人员使用高度准确的时间戳创建自定义性能指标。该方法window.performance.mark()创建一个时间戳,该名称被分配给该时间戳。该方法window.performance.measure()使您可以找出两次测量之间经过的时间。

//     
performance.mark('Movies:updateStart');
//  

//     
performance.mark('Movies:updateEnd');

//        
performance.measure('moviesRender', 'Movies:updateStart', 'Movies:updateEnd');

使用PerformanceChrome开发者工具标签对React应用程序进行性能分析时,您会发现一个部分,Timing其中包含有关React组件的临时指标。在渲染期间,React可以使用User Timing API发布此信息。


Chrome开发人员工具的“性能”选项卡

请注意,用户计时API已从React DEV程序集中删除,并用React Profiler API代替,后者可提供更准确的时间戳。也许将来会通过对那些支持User Timing Level 3规范的浏览器的支持来返回对该API的支持; 

在Internet上,您可能会发现使用User Timing API确定其指标的React网站。例如,这包括RedditTime to first post title visible指标和Spotify指标Time to playback ready


在React网站上使用的特殊指标

由用户计时API工具创建的指标可以方便地显示Chrome开发者工具 Lighthouse面板中


Lighthouse面板中的度量标准

例如, Next.js 的最新版本包括自定义度量标准和用于度量许多不同事件的机制。包括以下内容:

  • Next.js-hydration:使预渲染标记达到工作状态所需的时间。
  • Next.js-nav-to-render:从导航开始到渲染开始的时间。

所有这些测量值都显示在该区域中Timings


Next.js指标分析

开发人员工具和灯塔


提醒您,Lighthouse和PerformanceChrome开发者工具栏可用于深入分析加载过程和React应用程序的性能。在这里,您可以找到特别影响用户对网页的感知的指标。


页面性能分析

使用React的人可能会喜欢这样一个事实,即他们将拥有新的指标可供使用-例如总阻止时间(TBT)指标,该指标可提供有关页面在非交互模式下直到页面停留的时间的信息。可以可靠地在交互模式下工作(交互时间)。以下是采用实验性竞争模式的应用程序的TBT指标(“之前”和“之后”),该指标的使用有助于应用程序适应其运行环境的特征。


修改TBT

这些工具可用于分析应用程序性能瓶颈,例如需要很长时间才能完成的任务,从而延迟了应用程序的在线转换。例如,这可能与分析应用程序对按钮按下的反应速度有关。




此外, Lighthouse应用程序的分析为React开发人员提供了许多有关许多问题的特定技巧。以下是 Lighthouse 6.0中的分析结果在此处,将打开“删除未使用的JavaScript”部分,其中报告了已加载到应用程序中的未使用的JavaScript代码,可以使用导入该代码React.lazy()


在Lighthouse中分析

应用程序应用程序对测试硬件总是很有用的,它最有可能供最终用户使用。在这种情况下我经常依靠 Webpagetest以及 RUM CrUX数据,这使我可以获得有关应用程序性能的更完整信息。

亲爱的读者们!您如何研究React应用程序的性能?


All Articles