我如何将 Webpack 包大小缩减一半

2,570 阅读4分钟
原文链接: zhuanlan.zhihu.com
本文为译文,原文地址:jmduke.com/posts/how-i-,作者,@Justin Duke

当我最初建立 Buttondown 的时候,我专注于两个方面:

1. 它构建快速。

2. 它能很好的运行。

值得注意的是,不在列表中的是性能。Buttondown 并不是一个缓慢的应用程序,但是它很笨重:开发中的包文件以兆为单位,首次加载时间很长。

现在它的核心功能已经稳定下来了,没有什么特别紧急的需求了,我想把项目重心转向维护工作,其中一大部分是看看我能做些什么来减少包文件。

恩,是的,4M 大小,当然是未压缩的,但是对于 Buttondown 应用来说还是太大了。我决定将该大小减少一半,这就是我们从一开始就应用采取的结合最佳实践和常识的前端原则。

0. 分析包文件

我知道包文件很大,但我不知道为什么这么大。幸运的是,有一个工具webpack-bundle-analyzer 可以分析你的 webpack 数据,并且绘制出一幅可视化的树形图来查看占用空间比。

看起来如下图:

1. 抛弃 jQuery

“你真的需要 jQuery” 这是一个常见的问题,它有自己的网站,在这种情况下,答案是否定的。特别是因为 Vue 非常容易地捕获事件并引用 DOM,这是我实际使用它的唯一的两件事情。这是对比的样子:

包文件看起来是这样的:

这清除了大约 250k 字节,将包文件降低到 3.5M。不是很大的数据,但也不错。

2. 排除 moment locales

Moment 是处理时间的一个很重的解决方案。它拥有强大的 locales 支持,这是非常好的,但是目前我只是使用它来格式化某些 UTC 日期时间,所有包括所有这些 locales 设置似乎是不必要的。幸运的是,我发现了一种将它们从 webpack 中完全排除的方法

现在包文件看起这样:

这清除了大约 250k 字节,将包文件降低到了 3.25M。

3. 懒加载 zxcvbn

zxcvbn 是 Dropbox 处理密码验证的一个非常重要的库。 Buttondown 使用它来验证密码。

然而,它附带了一个 600KB 的经常使用的密码列表,这是非常重的密码。我本来想的是克隆该仓库并减少这个列表,就像其他人做的一样,但是这似乎并太理想。所以我决定尝试懒加载来推迟加载时间 — 实现 Webpack 懒加载。

对于延迟加载的一些配置要求(特别是正确的 publicPath 值)来说,这是非常烦人的,但最终的差异变得很好很紧凑。实际的代码改的有点笨拙,我不太喜欢实际的实现与 webpack 如何强耦合,但是结果却难以争辩。

现在包文件看起这样:

这清除了大约 750k 字节,将包文件降低到 2.5M,我们快要完成任务了!

4. 选择性的导出 lodash

最后,我将以最典型的例子作为结束,使用选定的内容来全面替换完整的 lodash 导入。

这很简单(也很无聊),导致一个非常无聊的差异,所以我只显示它的一个例子。放心,其余的看起来也差不多:

现在包文件看起这样:

这清除了大约 450k 字节,将包文件降低到了 2.08M,没到一半,但是很接近了。

下一步

2M 仍然很大(即使它未被压缩),它比我想的要大,但我对结果已经非常高兴了。我要了解更多关于 Webpack 的知识,提供代码库的质量,而较小的包文件对于跳出率有着重要的影响。

绝对有一些我可以做的事情来缩小代码空间:

1. 删除额外的字体。

2. 彻底摆脱 moment,并写一个定制的日期管理工具。

3. 懒加载 flatpickr(它只在几个地方使用)

这些都是后续改进内容。

扩展阅读

1. Paul Irish’s perf audit of Reddit

2. The Critical Request

3.Why our website is faster than yours

4. Optimizing your bundle size