首页 web前端 js教程 缩小 JavaScript 规模:掌握 Bundler 优化

缩小 JavaScript 规模:掌握 Bundler 优化

Dec 18, 2024 pm 05:58 PM

介绍

在过去的 15 年里,JavaScript 生态系统迅速扩展,引入了无数工具使开发变得更加容易。但这些工具是有代价的:增加捆绑包的大小。事实上,HTTP Archive 的数据显示,每页平均传输的 JavaScript 量已从 2010 年的 90 KB 激增至 2024 年的 650 KB(来源)。

尽管压缩技术的采用率不断提高并且取得了进步,但这一趋势并没有显示出放缓的迹象。随着我们不断添加功能,挑战仍然存在:我们如何才能减少 JavaScript 的数量?

奇怪的是,解决方案既简单又困难。最简单的部分是项目级别的调整,可以快速取得成果。困难的部分是产生持久的影响,这需要社区范围内的改变来改进捆绑器、库和工具。

本文重点关注您的项目的可行改进,涵盖:

  • 捆绑器:优化构建工具以减少输出大小。
  • :明智地选择和使用外部依赖项。
  • 您的项目:缩小捆绑包的实用步骤。

未来的文章将讨论我们可以做出的生态系统范围内的改进,但现在,让我们解决这些因素如何导致捆绑包膨胀 - 以及如何管理它们。

为什么优化 JavaScript 很重要

JavaScript 是现代网络交互背后的引擎,但它不是免费的。 JavaScript 是浏览器必须处理的计算成本最高的资源。它通常是决定页面感觉快还是慢的瓶颈,因为臃肿的包会阻止渲染并降低整体性能。

JavaScript 包越大,加载、解析、编译和运行所需的时间就越长。这会延迟其他一切 - 例如显示内容或让用户与页面交互。对于使用具有光纤连接的高端笔记本电脑的人来说,这可能是一个小烦恼。但对于使用低功率手机或不稳定网络的人来说,这可能是完全留在或离开您的网站的区别。

减少 JavaScript 包大小的第一步是 Tree Shaking(或“死代码消除”),大多数捆绑器都是开箱即用的。但所有捆绑商都是平等的吗?

捆绑者

JavaScript 中的捆绑已经取得了长足的进步——从手动串联和任务运行器到复杂的捆绑器。如今,捆绑器性能是一个关键焦点,开发人员优先考虑更快的构建。然而,构建速度并不是一切。同样重要的是它们生成的捆绑包的大小,因为较小的捆绑包意味着用户的加载时间更快。

为了寻求更好的性能,我们已经从使用 JavaScript 编写捆绑器转向 Rust 和 Go 等语言。此切换需要从头开始编写它们,因此旧捆绑器中存在的每个功能和优化都必须重新实现。从长远来看,这可能会得到回报。然而,从短期来看,这意味着它们缺少 JavaScript 捆绑器多年来开发的一些功能,例如良好的 tree shake。这正是可以帮助我们最小化捆绑包大小的功能。

基准

当然,空谈是廉价的,所以让我们看看数字,好吗?

让我们比较八个流行的库,并将它们与七个流行的捆绑器捆绑在一起。为了保持公平,我使用了:

  • 节点 22.12.0
  • 自我报告的构建时间
  • 第三次运行计时,让缓存预热,特别是对于像 Parcel 这样的工具
  • 删除所有注释(包括许可证)的配置,因为捆绑程序以不同的方式处理它们

您可以查看基准设置存储库以获取确切的配置。

经过测试的捆绑器:

  • esbuild (0.24.0)
  • 包裹(2.13.2)
  • 滚动(0.15.0-snapshot-993c4a1-20241205003858)
  • 汇总 (4.28.0)
  • Rspack (1.1.5)
  • Vite (6.0.3)
  • webpack (5.97.1)

请注意,在撰写本文时,Rolldown 仍处于 alpha 阶段,因此它处于劣势,随着时间的推移,其结果可能会有所改善。

测试过的库:

  • chart.js
  • ckeditor5
  • d3
  • 手工表
  • 勒克森
  • mobx
  • tippy.js
  • 佐德

这些库的大小和功能各不相同 - 有些库几乎可以像独立应用程序一样运行。

构建速度

让我们从构建速度开始,因为这是开发人员似乎非常关心的事情。将所有这些库捆绑在一起时,esbuild 是获胜者,其构建时间为 192 毫秒。与最慢的构建时间 7.23 秒相比,快了 37 倍以上。

Downsize your JavaScript: Mastering Bundler Optimizations

根据这些结果,我们可以将捆绑器分为三类:

  1. 极快™:esbuild、Parcel、Rolldown(
  2. 更快:Rspack(2.2 秒)。
  3. :Rollup、Vite、webpack(每个 5 秒)。

差异非常明显。例如,Rolldown 和 Rspack 分别比旧版本 Rollup 和 webpack 快 11.5 倍和 3.3 倍,同时保持理论上的向后兼容性。切换到这些较新的捆绑器可以显着提高大型项目的生产力。

输出尺寸

就输出大小而言,差异并不像构建时间那么大,但它们仍然很重要。

汇总结果

将所有八个库捆绑在一起时,Vite 是获胜者,输出大小为 2087 KiB。与最大输出大小 2576 KiB 相比,输出小了 23.5% 以上。

输出大小的 23.5% 差异是巨大的:在较慢的 3G 连接下,最小的包可能需要大约 5.7 秒才能下载,而最大的包可能需要大约 7 秒。解析和执行时间也会随着包的大小而变化,因此现实世界的差异可能更加明显。

Downsize your JavaScript: Mastering Bundler Optimizations

根据这些结果,我们可以将捆绑器输出再次分为三类:

  1. 最小:esbuild、Parcel、Rollup 和 Vite (~2085–2160KiB)。
  2. 好的:webpack (~2317KiB)。
  3. :Rolldown,Rspack (~2490–2580KiB)。

个别图书馆

聚合结果并不能描绘出全貌,因为您不太可能在项目中使用上面列出的所有库。更有趣的是这些捆绑器如何处理各个库。

Downsize your JavaScript: Mastering Bundler Optimizations

对于像chart.js和mobx这样的库,捆绑器的选择会极大地影响输出大小,差异达到70%。这凸显了使用特定依赖项测试捆绑器的重要性。在大多数其他情况下,差异要小得多,约为 20-30%。

此外,虽然 webpack 总体排名居中,但在 8 个案例中,有 6 个案例表现最好。然而,由于在捆绑handsontable和chart.js时它的表现要差得多,所以它最终还是这样。这意味着,根据您使用的库,webpack 可能是一个不错的选择。

另一方面,我们有 Rolldown。它在 8 个案例中的 7 个中表现最差(请记住,它仍处于 alpha 状态)。
Rspack 也是一个类似的故事。虽然它的性能比 Rolldown 更好,但它仍然生成了比其他捆绑器大得多的捆绑包。

如果您正在考虑迁移到较新的捆绑程序,使用您使用的库进行测试,看看更快的构建速度是否不会以增加输出大小为代价。

捆绑尺寸与输出速度

如图所示,较新的捆绑器速度更快,但可能会生成更大的捆绑包。从较旧的捆绑程序迁移时,不仅要比较构建时间,还要比较生成的捆绑包大小。您可能会发现自己用更快的构建来换取更大的捆绑包。

例如,在 Angular 从 webpack 切换到 esbuild 后,一些开发人员报告说,空的 Angular 应用程序的大小增加了约 20KB。这完美地突出了构建速度与捆绑包大小的权衡。

这并不是说您不应该关注构建速度,因为它对于开发人员的生产力和幸福感很重要。 CI 构建时间和合并代码所需的时间之间也存在相关性。

Downsize your JavaScript: Mastering Bundler Optimizations

选择捆绑器时,首先查看它提供的功能。然后目标是构建速度和包大小之间的平衡。选择可以在您方便的时间内生产尽可能最小的捆绑包的捆绑商。
测试项目中的一些代表性库。如果您的依赖项构成了代码库的大部分,那么您在这些基准测试中看到的差异可以很好地预测您的情况。

图书馆

我们列表中的下一个是外部库,它们通常构成 JavaScript 包的大部分。在我开发过的许多(如果不是大多数)应用程序中,它们占据了捆绑包大小的大部分。这就是为什么明智地选择(和使用)它们如此重要。

黄金但旧

我们中的许多人都安装了 lodash、axios 或 moment 等库,只是为了使用单个功能 - 导致应用程序臃肿。这些库很棒并且具有重要的历史意义,但随着它们变得越来越流行,更轻的替代品被创建,并且它们的一些功能被添加到语言本身中。

我们可以利用这一点。我可以列出这些库的本机 API 或更新且更小的替代方案,但已经有很多文章对此进行了介绍。还有很多其他库,不可能全部涵盖。

这就是为什么我只会给你一个一般性建议,让你看看你使用的库,看看是否可以删除它们或用本机 API 或更小的替代品替换它们。您可能不需要 * 网站是一个很好的入门资源。

优化安装路径

默认情况下,大多数库并未针对大小进行优化,但有些库提供特殊的安装路径或部分构建。即使在我们测试的库中,chart.js、handsontable 和 ckeditor5 也提供了一种通过仅包含您需要的部分来减小库大小的方法。让我们以 ckeditor5 为例。

Downsize your JavaScript: Mastering Bundler Optimizations

默认安装路径导致捆绑包大小在 660 到 800 KiB 之间。但是,如果我们使用优化的安装路径,捆绑包大小会下降到 603-653 KiB,仅 Rolldown 生成的捆绑包大小约为 750 KiB。大小减少了 7% 到 23%,具体取决于捆绑程序。

重复的依赖项

另一件事要注意的是重复的依赖关系。这是 JavaScript 应用程序中一个令人惊讶的常见问题。例如,Bluesky 嵌入小部件有两个版本的 zod 验证库。删除重复项使包大小减少了约 9%。

此问题通常不会发生,因为您拉取了同一库的两个不同版本,而是因为您和外部库之一依赖于同一库,但版本不同。这通常可以通过更新您所依赖的库来解决。

你的项目

考虑到所有这些,我们终于可以进入最后一块拼图 - 您的项目。您可以采取以下措施来缩小捆绑包并提高性能。

检查您的捆绑包

第一步是可见性。如果不了解捆绑包中的内容,减小捆绑包的大小就变成了一场猜谜游戏。为此,您可以使用我创建的名为 Sonda 的捆绑分析器和可视化工具。它适用于上述大多数捆绑程序(Parcel 除外),并准确显示参与捆绑的各个文件的大小。

您可以首先将其安装到您的项目中并目视检查捆绑包的各个部分。

Downsize your JavaScript: Mastering Bundler Optimizations

一旦您充分了解了捆绑包内的内容并确定了可以优化的部分,您就可以单击图表图块来查看:

  • 压缩前后的文件大小,
  • 导入所选文件的文件列表,
  • 甚至检查捆绑包中包含的部分源代码。

Sonda 还会警告您重复的依赖项,以便您可以快速识别并修复问题的根源。

理想情况下,您不仅应该进行一次性检查,还应该将持续监控设置为 CI 管道的一部分。跟踪一段时间内的变化,尤其是在大型项目中,可以帮助您防止小变化随着时间的推移滚雪球般变成严重的膨胀。

删除或优化外部库

最快的代码是您发送的代码。只要有可能:

  • 删除可以被原生 API 替换的库。
  • 将重量级库替换为较小的替代品。
  • 如果库支持,请使用优化的安装路径。

使用代码分割

如果您无法删除应用程序的某些部分,请尝试代码拆分。代码分割允许您推迟加载应用程序的某些部分,直到需要它们为止,从而缩短初始加载时间。

使用动态 import() 按需加载模块。例如,如果在用户单击按钮之前不需要某个特定功能,则推迟加载该功能直到那一刻。

现代前端框架支持开箱即用的延迟加载,使将代码分割集成到您的工作流程中比以往更容易。

遵循最佳实践

这是一般性建议,但值得重复。遵循最佳实践,例如:

  • 使用最新的目标,这样代码就不会被不必要的转译或填充。一些polyfills可以添加很多现代浏览器中根本不需要的代码,但许多环境仍然默认添加它们。您还可以设置提醒,每年更新目标。
  • 定期更新依赖项,因为新版本通常会更小或更快。这还可以防止您不得不处理安全漏洞或重复的依赖项。
  • 评估您已经拥有或正在考虑添加的每个依赖项。如果您无法证明大小合理,请不要添加它或寻找更小的替代方案。

加入生态系统绩效 (e18e) 社区

如果您有兴趣让网络更快或只是学习新事物,您应该考虑加入生态系统性能社区。我们专注于三个主要领域:

  • 清理 - 通过删除冗余依赖项或用现代替代方案替换它们来改进软件包。
  • 加速 — 提高广泛使用的软件包的性能。
  • 升级——构建过时软件包的现代替代品。

结论

我希望这篇文章说明您可以用更少的代码提供相同的功能。如果不加以管理,捆绑包大小可能会失控,但即使很小的更改也可以显着提高性能。

从今天开始:分析您的包、测试新工具或替换重量级库。其影响会让你大吃一惊。


我希望您喜欢这篇文章。如果您有任何问题或意见,或者如果您想了解有关特定主题的更多信息,请在下面的评论中告诉我。如果您想了解有关 JavaScript 性能、捆绑和 tree-shaking 主题的更多信息,您可以在此处关注我或在 BlueSky 上关注我并加入 e18e 社区。

以上是缩小 JavaScript 规模:掌握 Bundler 优化的详细内容。更多信息请关注PHP中文网其他相关文章!

本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

Video Face Swap

Video Face Swap

使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热工具

记事本++7.3.1

记事本++7.3.1

好用且免费的代码编辑器

SublimeText3汉化版

SublimeText3汉化版

中文版,非常好用

禅工作室 13.0.1

禅工作室 13.0.1

功能强大的PHP集成开发环境

Dreamweaver CS6

Dreamweaver CS6

视觉化网页开发工具

SublimeText3 Mac版

SublimeText3 Mac版

神级代码编辑软件(SublimeText3)

热门话题

Java教程
1653
14
CakePHP 教程
1413
52
Laravel 教程
1304
25
PHP教程
1251
29
C# 教程
1224
24
前端热敏纸小票打印遇到乱码问题怎么办? 前端热敏纸小票打印遇到乱码问题怎么办? Apr 04, 2025 pm 02:42 PM

前端热敏纸小票打印的常见问题与解决方案在前端开发中,小票打印是一个常见的需求。然而,很多开发者在实...

神秘的JavaScript:它的作用以及为什么重要 神秘的JavaScript:它的作用以及为什么重要 Apr 09, 2025 am 12:07 AM

JavaScript是现代Web开发的基石,它的主要功能包括事件驱动编程、动态内容生成和异步编程。1)事件驱动编程允许网页根据用户操作动态变化。2)动态内容生成使得页面内容可以根据条件调整。3)异步编程确保用户界面不被阻塞。JavaScript广泛应用于网页交互、单页面应用和服务器端开发,极大地提升了用户体验和跨平台开发的灵活性。

谁得到更多的Python或JavaScript? 谁得到更多的Python或JavaScript? Apr 04, 2025 am 12:09 AM

Python和JavaScript开发者的薪资没有绝对的高低,具体取决于技能和行业需求。1.Python在数据科学和机器学习领域可能薪资更高。2.JavaScript在前端和全栈开发中需求大,薪资也可观。3.影响因素包括经验、地理位置、公司规模和特定技能。

如何实现视差滚动和元素动画效果,像资生堂官网那样?
或者:
怎样才能像资生堂官网一样,实现页面滚动伴随的动画效果? 如何实现视差滚动和元素动画效果,像资生堂官网那样? 或者: 怎样才能像资生堂官网一样,实现页面滚动伴随的动画效果? Apr 04, 2025 pm 05:36 PM

实现视差滚动和元素动画效果的探讨本文将探讨如何实现类似资生堂官网(https://www.shiseido.co.jp/sb/wonderland/)中�...

JavaScript难以学习吗? JavaScript难以学习吗? Apr 03, 2025 am 12:20 AM

学习JavaScript不难,但有挑战。1)理解基础概念如变量、数据类型、函数等。2)掌握异步编程,通过事件循环实现。3)使用DOM操作和Promise处理异步请求。4)避免常见错误,使用调试技巧。5)优化性能,遵循最佳实践。

JavaScript的演变:当前的趋势和未来前景 JavaScript的演变:当前的趋势和未来前景 Apr 10, 2025 am 09:33 AM

JavaScript的最新趋势包括TypeScript的崛起、现代框架和库的流行以及WebAssembly的应用。未来前景涵盖更强大的类型系统、服务器端JavaScript的发展、人工智能和机器学习的扩展以及物联网和边缘计算的潜力。

如何使用JavaScript将具有相同ID的数组元素合并到一个对象中? 如何使用JavaScript将具有相同ID的数组元素合并到一个对象中? Apr 04, 2025 pm 05:09 PM

如何在JavaScript中将具有相同ID的数组元素合并到一个对象中?在处理数据时,我们常常会遇到需要将具有相同ID�...

前端开发中如何实现类似 VSCode 的面板拖拽调整功能? 前端开发中如何实现类似 VSCode 的面板拖拽调整功能? Apr 04, 2025 pm 02:06 PM

探索前端中类似VSCode的面板拖拽调整功能的实现在前端开发中,如何实现类似于VSCode...

See all articles