使用 webpack 设置性能预算

Milica Mihajlija
Milica Mihajlija

Webpack 会合并您导入的所有文件,并将它们打包到一个或多个输出文件(称为软件包)中。捆绑很方便,但随着应用的发展,您的软件包也会随之增多。您需要监控软件包大小,以确保其不会变得过大,从而影响应用的加载时间。Webpack 支持根据资源大小设置性能预算,并可为您密切关注软件包大小。

下面是一个用于统计新年到来还有多少天数的应用,您可以通过它来了解该功能的运作方式。它是使用 Reactmoment.js 构建的。(就像现实世界的应用越来越依赖框架和库一样。😉?)

用于统计距离新年还有多少天的应用

测量

此 Codelab 已包含与 webpack 捆绑的应用。

  1. 点击 Remix to Edit 即可修改项目。
  2. 点击终端(注意:如果系统未显示“终端”按钮,您可能需要使用“全屏”选项)。
  3. 如需获取按颜色编码的资源及其大小列表,请在控制台中输入 webpack
webpack

主软件包以黄色突出显示,因为其大小超过 244 KiB (250 KB)。

显示 bundle 大小为 323 KiB 的 Webpack 输出
Webpack 提醒您 JS 文件包过大 ⚠️

这些警告在生产模式下默认处于启用状态,默认阈值为 244 KiB 未压缩,适用于资源和入口点(网页初始加载期间使用的所有资源的组合)。

Webpack 警告资源超出建议的大小限制
Webpack 提醒您 JS 文件包过大 ⚠️

Webpack 不仅会向您发出警告,还会就如何缩减软件包大小为您提供建议。如需详细了解推荐的技术,请参阅网站开发基础

Webpack 性能优化建议
Webpack 性能优化建议 💁?

设置自定义效果预算

适当的性能预算取决于项目的性质。最好还是自行开展调研一般来说,压缩/缩减后的关键路径资源应不超过 170 KB。

对于这个简单的演示,请尝试更加保守,将预算设置为 100 KB (97.7 KiB)。在 webpack.config.js 中添加以下代码:

module.exports = {
  //...
  performance: {
    maxAssetSize: 100000,
    maxEntrypointSize: 100000,
    hints: "warning"
  }
};

新的效果预算以字节为单位进行设置:

  • 单个资源的大小上限为 100,000 字节 (maxAssetSize)
  • 入口点的 100,000 字节 (maxEntrypointSize)

在本例中,只有一个软件包,它同时充当入口点。

hints 的可能值如下:

  1. warning(默认值):显示黄色警告消息,但 build 会通过。最好在开发环境中使用此方法。
  2. error:显示红色错误消息,但 build 仍会通过。建议将此设置用于生产 build。
  3. false:系统不会显示任何警告或错误。
红色字体显示的 Webpack 性能错误
Webpack 性能提示“错误”🚨?

优化

性能预算的目的是在性能问题变得难以解决之前提醒您。构建应用的方法总是有多种,有些方法可以缩短加载时间。(许多此类问题都记录在优化 JavaScript 中。🤓?)

框架和库可以让开发者的生活更轻松,但最终用户并不关心应用是如何构建的,只关心应用是否功能强大且运行速度快。如果您发现自己超出了效果预算,就需要考虑可能的优化措施。

在现实世界中,大型客户端框架通常很难替换,因此请务必明智地使用它们。通过一些研究,您通常可以找到与热门库功能相当且体积更小的替代库(date-fnsmoment.js 的绝佳替代库)。有时,如果某个框架或库会对性能产生重大影响,则完全不使用它会更明智。

移除未使用的代码是优化包含大型第三方库的应用的好方法。“移除未使用的代码”指南详细介绍了此过程,下面介绍了一种无需使用 moment.js 即可快速重写倒计时代码的方法。

app/components/Countdown.jsx 中,移除以下代码:

const today = moment();
const yearEnd = moment().endOf('year');
const daysLeft = yearEnd.diff(today, 'days');

并删除以下行:

const moment = require('moment');

这需要一些数学知识,但您可以使用原生 JavaScript 实现相同的倒计时:

const today = new Date();
const year = today.getFullYear();
const yearEnd = new Date(year,11,31); //months are zero indexed in JS
const timeDiff = Math.abs(yearEnd.getTime() - today.getTime());
const daysLeft = Math.ceil(timeDiff / (1000 * 3600 * 24));

现在,从 package.json 中移除 moment.js,然后再次在控制台中运行 webpack 以构建经过优化的软件包。

大功告成!您已缩减 223 KiB (230KB),应用的大小已低于预算。🎉?

优化后的 Webpack 软件包大小输出为 97.7 KiB

监控

在 webpack 中设置性能预算只需几行代码,如果您(意外地)添加了大型依赖项,系统会向您发出警告。俗话说“眼不见心不烦”,但 webpack 可以确保您随时了解性能影响。