使用 webpack 设置性能预算

米利卡·米哈吉利亚 (Milica Mihajlija)
Milica Mihajlija

Webpack 会将您导入的所有文件合并成一个或多个输出文件(称为软件包)。捆绑功能整洁有序,但随着应用体量的增加,捆绑包也会随之增多。您需要监控软件包大小,以确保它们不会变得太大并影响应用的加载时间。Webpack 支持根据资源大小设置性能预算,并且它可以监控软件包大小。

要查看实际情况,该应用会计算距新年剩余的天数。 它使用 Reactmoment.js 构建而成。(就像现实世界中越来越依赖框架和库的应用一样。😉)

一款应用,可以计算距新年结束的天数

测量

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

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

主软件包以黄色突出显示,因为它大于 244 KiB (250 KB)。

Webpack 输出显示软件包大小为 323 KiB
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)
  • 入口点为 100000 字节 (maxEntrypointSize)

在本例中,只有一个 bundle 也充当入口点。

提示的可能值包括:

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

优化

性能预算的用途是在性能问题变得难以解决之前向您发出警告。构建应用的方法总是多种多样,而有些技术可以加快加载时间。(优化 JavaScript 中介绍了很多方法。🤓)

框架和库让开发者的工作更轻松,但最终用户并不真正关心应用的构建方式,只关心应用的功能和快速运行。如果您发现超出了性能预算,则是时候考虑可能的优化措施了。

在现实世界中,大型客户端框架通常很难替换,因此明智地使用它们非常重要。经过一些研究,您通常可以找到常用库的较小替代方案,而这些库同样可以代替 moment.jsdate-fns 是很好的替代方案)。有时,如果框架或库会严重影响性能,则完全不使用该框架或库更合理。

移除未使用的代码是优化包含大型第三方库的应用的好方法。如需详细了解此过程,请参阅“移除未使用的代码”指南,下面提供了一种在不使用 remember.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 可以确保你始终了解性能影响。