分析一个React应用程序的性能

Posted YITA90

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了分析一个React应用程序的性能相关的知识,希望对你有一定的参考价值。


如何使用 React DevToolsReactProfile 来正确分析生产应用程序。

The React DevTools是一款非常棒的软件,而且可以作为 ChromeFirefox 的浏览器扩展,便于在随时随地链接 React 应用。

React DevTools 最酷的功能之一就是它的分析功能。profiler 包括很多东西,本文不一一列举,但是会教你如何开始使用 React Profiler,避免一些常见问题。

我会用我开发的我的书架应用来进行介绍,应用很容易理解,不需要了解业务背景,当然,你也可以用你自己的应用来跟我学习。

安装扩展

第一步是确保为你正在使用的浏览器可以安装 React DevTools 扩展。 我使用 Chrome,所以我把它安装在了 Chrome WebStore 中。 如果在你安装扩展后没有显示,你可能需要关闭你浏览器的 DevTools 面板,重新打开它们。

启动应用程序

Bookbook 应用程序使用 react-scripts (感谢 create-react-app) 构建,因此在本地安装项目之后,运行 npm run start 来启动项目。 这时在浏览器打开 http://localhost:3000

启动 Profiler 会话

在页面上的任意地方通过右键点击,并选择 “Inspect” 来打开浏览器开发工具,然后选择 “Profiler” 选项卡。 这就是 React DevTools 分析器,现在您可以单击蓝色小圆圈来“启动分析”应用程序。

从这里开始,继续与应用程序进行交互,比如在页面上注册一个新帐户,然后单击红色小圆圈“停止分析”。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9s3wXsYG-1569812781487)(https://kentcdodds.com/static/2c3dc178ed34a54a1f4e0bb21ecde137/781de/3.png)]

研究分析数据

这时,我们会看到,DevTools 会有和应用程序交互时,收集到的数据结果。默认视图是“火焰图表” ,还有“排名图表”,下图是“火焰图表”的样子 (如果你想看“排名图表” ,你必须自己动手):


本文不做深入解析这些数据。

陷阱:开发模式测试

我想指出一个严重的陷阱,您在进行性能测量(如分析)时需要避免这个陷阱。 我们正在开发模式下测量我们应用的表现。 如果您使用 React 已经有一段时间了,那么您很可能会意识到它附带了大量的开发时警告,帮助我们远离有问题代码和实践。 这正是我最喜欢 React的原因之一,但这需要付出很大的性能代价。

因此,在开发环境下, React 在开发环境下,执行了您的用户永远不需要允许的代码,导致测量结果不准。

如果您需要得到准确的性能测试结果,请确保您使用的是生产版本的代码(最终用户会使用的代码)。

构建和测量生产应用程序

因此,让我们先运行 npm run build 对代码进行生产构建。 接下来,我们将运行 npx serve -s build,为 build 版本的代码启动一个 HTTP Server。 这样就可以在端口 5000 上启动应用程序。 接着,我们再打开分析面板… … 等等! 哦,不! 这是什么?

不支持分析。
分析支持需要 React v16.5 + 的开发或生产分析构建。
更多详情

事实证明,React 为了让应用尽可能快速的运行,为 profile 分析添加了特殊的代码,但在实际生产构建中删除了这些代码。好吧,那现在我们该怎么办? 你可以继续阅读本文,后面会告诉你该怎么做。

更新 webpack 配置以进行生产概要分析

正如消息中提到的,React生产版本删除了部分开发版本中的代码,但仍然保留了 profile 相关代码,对性能会有一些影响,但是可以让我们对组件在生产环境的表现有所了解。

有几种方法可以解决这个问题,最简单的就是更新 webpack 配置,将特定模块的任何引用更改为该模块的分析版本。 有两个这样的模块:

  • react-dom -> react-dom/profiling
  • scheduler/tracing -> scheduler/tracing-profiling

这两个都是 React 包,需要特殊代码才能让分析器工作。

如何更新你的 webpack 配置取决于你正在使用的框架(create-react-appnext.jsgatsby.js 或者你自己的原始 webpack)。 在我们的例子中,我们使用的是 create-react-app,没有官方支持的方法来扩展或修改 webpack 配置。 幸运的是,我们在本地做这件事的话,我们可以修改我们的 node_modules

因此,如果您使用 react-scripts@3.1.1(或者其他地方) ,那么您可以在这里打开 webpack 配置: ./node_modules/react-scripts/config/webpack.config.js

然后找到这样的代码并添加注释行:

// ... config ...
resolve: 
  // ... config ...
  alias: 
    // Support React Native Web
    // https://www.smashingmagazine.com/2016/08/a-glimpse-into-the-future-with-react-native-for-web/
    'react-native': 'react-native-web',
    'react-dom$': 'react-dom/profiling',
    'scheduler/tracing': 'scheduler/tracing-profiling',
  ,
  // ... more config ...

// ... more config ...

分析生产分析构建

很好,现在运行 npm run build,然后 npx serve -s build,让我们再次对应用程序进行配置! 我将按照上次同样的注册步骤进行操作。 以下是我得出的结论:

太棒了! 你可能会注意到,和上次相同的操作(它的渲染后注册页面) ,我们从13.7毫改进到了6.5毫秒。

图片里有很多的Anonymous组件,是什么呢?有一个叫 ee的组件调用了 Z 组件? 这是怎么回事? 这是因为为了更快的为用户加载页面,编译代码,代码做了混淆和压缩。但对于我们做性能检测就会比较不容易阅读,很难分析到哪个组件引起的性能问题。

禁用函数名改变

根据组件的 name 属性,React 知道该如何调用组件:

function AwesomeAppComponent() 
  return <div>Awesome</div>

console.log(AwesomeAppComponent.name) // <-- logs "AwesomeAppComponent"
class LessAwesomeAppComponent extends React.Component 
  render() 
    return <div>Less Awesome</div>
  

console.log(LessAwesomeAppComponent.name) // <-- logs "LessAwesomeAppComponent"

当我们使用“uglifier”或“ minifier”构建代码时,这个工具会在不影响功能的情况喜爱,改变这些组件名称,减少 javascript 生产文件的文件大小,从而提高性能:

function a() 
  return <div>Awesome</div>

console.log(a.name) // <-- logs "a"
class b extends React.Component 
  render() 
    return <div>Less Awesome</div>
  

console.log(b.name) // <-- logs "b"

这就是为什么我们在性能测试中看到这些有趣的名字。 所以我们需要禁用这个功能。

Create React App 通过 Terser-webpack-plugin 使用一个名为 Terser 的工具来进行压缩,所以我们只需要更新配置来保留函数和类名。

所以在同一个 webpack 配置文件中,向下滚动到插件配置的位置,然后像这样修改它:

// ... some config ...
new TerserPlugin(
  terserOptions: 
    // ... some other config ...
    mangle: 
      safari10: true,
    ,
    keep_classnames: true,
    keep_fnames: true,
    // ... some more config ...
  ,
  // ... even more config ...
)

keep classnameskeep fnames 配置为 true,现在让我们尝试构建应用程序代码并再次运行一个分析会话!

太棒了!现在我们有了一个带着组件名的分析结果,向我们展示了所有组件的名称,它们使用的代码与我们的最终用户将要运行的代码非常相似!

陷阱: 使用快速计算机进行分析

我向你保证,现在阅读这篇文章的大多数人正在使用一个比大多数人使用的应用程序更强大的设备来开发你的应用程序。 没有什么能代替在用户将要使用的设备上尝试你的应用程序。 也就是说,如果你调节你的 CPU 来模拟你的应用程序的一些用户的体验,你可以更好地了解你的应用程序的实际性能。

我敢打赌,大部分正在阅读这篇文章的人,开发应用程序是使用设备,而不是大部分在用的软件开发工具。用设备当然会更好一些。也就是说,如果你用你的 CPU 来模拟用户使用场景,你可以更好的了解实际性能情况。

所以我们就这么做吧。点击 Chrome DevTools 的“性能”标签,然后在齿轮图标上显示设置,然后在 CPU 选项上,选择“6倍减速”。

现在再试一下,看看有什么不同:

呼!31.8毫秒!那是相当慢的速度!在这篇名为渲染性能的博客文章中了解更多关于这段时间对用户体验的影响。
想了解更多关于用户体验的话,可以看这篇文章——渲染性能 。还有其他的值得研究的东西,可以在以后的文章里介绍。

总结

现在,你应该知道如何正确的使用 React 应用程序分析工具里,希望可以在项目中亲自实践,探索你的应用程序的性能。

另外,如果你想进一步了解 React DevTools这篇关于 React blog 的博客文章可以帮助你

祝你好运!

以上是关于分析一个React应用程序的性能的主要内容,如果未能解决你的问题,请参考以下文章

分析一个React应用程序的性能

React.js 性能分析

C 中的性能/分析测量

R语言中多分类问题 multicalss classification 的性能测量

Android性能优化之启动耗时测量

Android性能优化之启动耗时测量