React应用加速四倍

如果加载时间超过3秒,则将近60%的网站访问者会离开它。 80%的此类访问者不再返回该站点。 这表明,Web项目的成功不仅仅取决于其速度。 该材料的作者(我们今天将其翻译发布)想谈谈提高React应用程序性能的技术。


应用优化结果

基准测试


在向您介绍如何加速应用程序之前,我想显示一些数字。 在这里进行测量是为了期望它们可以通过现代标准较慢的连接与应用程序一起工作。 但应注意,实际上大多数用户将具有更快的连接。

  • 在通过Chrome开发者工具的“网络”标签进行测量时,数据传输速率被强制限制为快速3G连接级别。
  • 在禁用缓存的情况下获得的“首次加载”度量。
  • 2nd Load指示灯指示在打开缓存时重新加载应用程序的时间。

如您所见,优化和未优化的应用程序之间的差异非常大。 这在慢速网络中尤其明显。

使用source-map-explorer检查了应用程序捆绑包的大小。 该工具还使您知道各种库占用了多少空间。 可以在图顶部看到的指标是使用Google Lighthouse测量的。

现在,我将讨论如何优化应用程序。

1.使用CSS代替CSS-in-JS


在该应用程序的旧版本中,我使用了样式组件库。 为什么这样不好? 事实是,普通CSS更快,占用空间更少。 现代的浏览器可以与JavaScript包并行加载CSS代码。 此外,您不需要额外的库即可使用常规CSS。 样式化组件的缩小版本大约需要54 Kb。 使用常规CSS代替样式化组件会导致以下事实:应用程序代码加载速度更快,并且在更改样式时,系统必须执行较少的计算。


仅仅放弃样式化组件库并切换到常规CSS即可减少大约0.3秒的网站加载时间

如果CSS比实现CSS-in-JS的技术允许更好的性能,则您可能想知道为什么开发人员使用此组件样式技术。 选择CSS-in-JS的原因之一是,该技术允许您限制样式范围并放弃全局样式。 使用应用程序主题很方便。 也许有人喜欢那样设计React应用程序。

scope范围有限的样式


现在,Create-react-app正式支持有限范围的CSS模块 。 这意味着您可以限制样式的范围,而无需使用其他库。

▍主题


如果使用styled-components库,则为了使用定义主题的变量,只需将这些变量包装在ThemeProvider 。 所有这些都很好,但是截至2019年5月,有91%的浏览器支持类似的标准CSS功能。

如果您认为91%的指标还不够好,请考虑它可能不会那么小。


CSS变量支持

实际上,如果您对IE支持不感兴趣,则可以安全地在项目中使用CSS变量 。 如果您对此主题感兴趣-建议您看一下材料。

2.避免使用大型CSS库



包装分析材料-ui

我是Material Design的忠实粉丝。 已经为React编写了一个名为material-ui的很棒的Material库。 该库只有一个问题。 这是她的尺寸。 她非常棒。 即使仅使用其单独的组件,其CSS-in-JS机制的实现也将包含在捆绑包中,这大约是30 Kb的最小代码。

有哪些选择? 我决定构建自己的组件,并在创建应用程序的过程中对它们进行样式设置。 选择该选项的原因之一是我想重新学习CSS知识。 而且我已经很长时间没有编写CSS代码了。 但是,还有其他可能性。 特别是,我们谈论的是CSS框架,其大小远小于material-ui的大小。 例如,这些是Spectre和Bulma,它们的代码在GZIP压缩后分别需要9和40 Kb。


幽灵-GZIP压缩后9 Kb


Bulma-GZIP压缩后40 Kb

3.延迟加载页面


因此,您的路由器具有许多导入的页面。 如果我们谈论的是几页-这里没有问题。 但是随着页面数量的增加,网站首次显示的时间也会增加。 导入命令如下所示:

 import NotFound from "pages/NotFound"; import Projects from "pages/Projects"; import Project from "pages/Project"; 

如何改善呢? 对我们来说幸运的是,React可以组织延迟页面加载。 组件代码也是如此,可以将其分解为小片段,并在必要时加载。 看起来是这样的:

 import React, { lazy, Suspense } from "react"; const load = (Component: any) => (props: any) => (   <Suspense fallback={<Loader />}>       <Component {...props} />   </Suspense> ); const NotFound = load(lazy(() => import("pages/NotFound"))); const Projects = load(lazy(() => import("pages/Projects"))); const Project = load(lazy(() => import("pages/Project"))); 

4.渐进式Web应用技术


渐进式Web应用程序使用服务工作者。 它们允许用户将应用程序添加到其设备的主屏幕。 但这不限于服务人员选项。 特别是,它们能够显着改善缓存。 这导致以下事实:在首次下载后,该应用程序将加载得更快。

5.摆脱看似有趣但不会带来太大好处的软件包


在我的原始项目中,当我安装组件时,我使用了很多动画来动画化页面的加载。 所有这些不仅降低了页面速度。 这使她慢了很多。 我看着网站,并为它看起来多么可爱而高兴,直到某一点都没有考虑性能。 但是该网站不仅具有动画效果。 还有其他类似的装饰品。 例如,使用一个按钮,您可以转到页面顶部。 例如-某些元素的动画加载。 我喜欢所有这些,但是经过仔细检查后发现,例如,该网站在不是最快的设备上确实运行缓慢。 此外,起初我仅在笔记本电脑上测试了该站点,所以没有立即了解它。

我还有一个滑块组件,我将其添加到页面中时并没有过多考虑其“重量”。 我用它来播放幻灯片。 后来证明,此滑块的代码以最小形式占用30 Kb。 然后,我决定自己创建幻灯片放映的组件。 最后,它的压缩代码占用25 KB。 该卷包括一个好的动画库和一个用于处理手势的系统,该系统不仅可以用于幻灯片放映,还可以在应用程序的其他部分使用。 看来我所做的工作比第三方解决方案要好得多。

这是NPM的滑块。


NPM滑块

这是我的滑块


自行开发的滑块(在生活中,它比低帧频的GIF图像更流畅)

这里查看此滑块的操作。

▍捆束尺寸分析


如果您使用create-react-app,那么分析捆绑包的组成非常容易。 为此,请运行npm run build ,然后npm run build npx source-map-explorer "build/static/js/*.js" 。 之后,将打开一个页面,其中包含有关包的组成的信息,类似于以下所示的页面。


捆绑信息

总结


如您所见,加速React应用程序并不难。 仔细监视它们的构建,对其进行测试并对其进行适当的更改就足够了。 这是在改进之前和之后在这里讨论项目。

如果您对优化React应用程序感兴趣,请参阅以下有关此主题的出版物:


亲爱的读者们! 您是否有成功(或失败)优化React应用程序的示例?



Source: https://habr.com/ru/post/zh-CN455505/


All Articles