webpack 拆分是否有助于节省 AWS 成本?
Does webpack splitting good for saving AWS cost?
我们的网站是用重 node_modules
构建的。
许多沉重的包裹导致沉重 node_modules
并最终影响 AWS 上的沉重成本。
所以我们正在尝试减少总包大小以降低一些成本。
我发现,通过使用 webpack 拆分代码,我们可以拥有更多但更小的包。不过,整体尺寸变化不大。
我想知道的是,使用 webpack 拆分代码是否可以节省一些 AWS 成本?
不好意思,我现在能想到的就这些了。
任何好主意都会很有帮助谢谢。
这是一个复杂的话题,同样也是 open-ended 的问题!为了回答这个问题,我将做一些假设:
- 通过节省 AWS 成本,这意味着减少捆绑包大小,从而节省传出带宽成本。
- 正在构建的应用程序是 100% SPA,即完全 client-side。 Server-side 优化很快变得非常复杂。
开箱即用,Webpack 会将所有内容打包成一个大 file/bundle。它包含您自己的代码以及来自 third-party 库的代码。 这里的基本思想是 third-party 代码很少更改,而我们自己的代码经常更改。
因此,我们可以使用 Webpack 使用 SplitChunksPlugin 将代码拆分为两个不同的块。一个用于我们自己的代码,另一个用于 third-party 代码,即来自 node_modules
文件夹的代码;让我们称之为供应商包。现在,只要您的 node_modules
文件夹保持不变,即您的锁定文件 - package-lock.json
文件是不变的,它将始终为 third-party 代码生成具有完全相同内容的相同包。
接下来的想法是您可以简单地获取此供应商包并将其上传到 CDN,然后通过 CDN 使用。 CDN 和浏览器会发挥它们的缓存魔力,用户几乎不需要每次都下载这个文件。 CDN 将使用 ETag
and/or cache-control
header 来实现这一点,浏览器将使用那个。
然而,现实是不同的。当你有太多的依赖和/或使用 dependabot 来更新依赖时,你会经常更新你的锁文件。这意味着在每次构建时都会生成一个新的供应商包,即使存在单个字节的差异也是如此。 Webpack 生成的 hash id 会不同。在其他情况下,您导入依赖项的方式也可能会更改生成的包内容,从而导致不同的包。
因此,在架构上,我们通过使用 CDN 来更好地捆绑供应商。第一步是区分稳定的third-party模块和经常更新的third-party模块。例如,考虑 react
、react-dom
和 rxjs
等。这些并不经常更新。对于这些库,请使用 third-party CDN,如 cloudflare、cdnjs 或 unpkg。将这些库添加为基于 CDN 的 UMD 包。
为此,您需要将这些依赖项添加到通常使用 html-webpack-plugin
.
生成的 index.html
文件中
<!-- index.html -->
<script crossorigin src="https://unpkg.com/react@18/umd/react.production.min.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@18/umd/react-dom.production.min.js"></script>
现在,只需告诉 Webpack 不要捆绑这些您已经通过 CDN script
提供的依赖项。使用 Webpack externals 来做到这一点:
// webpack.config.js
module.exports = {
externals: {
'react': 'React',
'react-dom': 'ReactDOM'
},
};
通过这种配置,Webpack 不仅会从捆绑中排除 React,还会加快您的捆绑速度。无论你从 React 库中导入什么,Webpack 都会将其替换为全局 object React
.
然后您可以将此模型扩展到您正在使用的所有稳定库。 使用这种方式的另一个重要优势是,您的用户可能已经访问过其他网站,这些网站会使用相同的 CDN 在他们的浏览器中缓存此特定文件。
要自动化您的工作流程,您可以自定义 Webpack 或任何捆绑器脚本,通过读取依赖项的 packge.json
文件然后生成 <script>
标记来注入这些脚本的确切版本。这意味着您的依赖项版本仍然拥有单一的真实来源。您可以阅读 CDN documentation 以了解它们如何允许您为依赖项构建 CDN URL。
我们的网站是用重 node_modules
构建的。
许多沉重的包裹导致沉重 node_modules
并最终影响 AWS 上的沉重成本。
所以我们正在尝试减少总包大小以降低一些成本。
我发现,通过使用 webpack 拆分代码,我们可以拥有更多但更小的包。不过,整体尺寸变化不大。
我想知道的是,使用 webpack 拆分代码是否可以节省一些 AWS 成本?
不好意思,我现在能想到的就这些了。
任何好主意都会很有帮助谢谢。
这是一个复杂的话题,同样也是 open-ended 的问题!为了回答这个问题,我将做一些假设:
- 通过节省 AWS 成本,这意味着减少捆绑包大小,从而节省传出带宽成本。
- 正在构建的应用程序是 100% SPA,即完全 client-side。 Server-side 优化很快变得非常复杂。
开箱即用,Webpack 会将所有内容打包成一个大 file/bundle。它包含您自己的代码以及来自 third-party 库的代码。 这里的基本思想是 third-party 代码很少更改,而我们自己的代码经常更改。
因此,我们可以使用 Webpack 使用 SplitChunksPlugin 将代码拆分为两个不同的块。一个用于我们自己的代码,另一个用于 third-party 代码,即来自 node_modules
文件夹的代码;让我们称之为供应商包。现在,只要您的 node_modules
文件夹保持不变,即您的锁定文件 - package-lock.json
文件是不变的,它将始终为 third-party 代码生成具有完全相同内容的相同包。
接下来的想法是您可以简单地获取此供应商包并将其上传到 CDN,然后通过 CDN 使用。 CDN 和浏览器会发挥它们的缓存魔力,用户几乎不需要每次都下载这个文件。 CDN 将使用 ETag
and/or cache-control
header 来实现这一点,浏览器将使用那个。
然而,现实是不同的。当你有太多的依赖和/或使用 dependabot 来更新依赖时,你会经常更新你的锁文件。这意味着在每次构建时都会生成一个新的供应商包,即使存在单个字节的差异也是如此。 Webpack 生成的 hash id 会不同。在其他情况下,您导入依赖项的方式也可能会更改生成的包内容,从而导致不同的包。
因此,在架构上,我们通过使用 CDN 来更好地捆绑供应商。第一步是区分稳定的third-party模块和经常更新的third-party模块。例如,考虑 react
、react-dom
和 rxjs
等。这些并不经常更新。对于这些库,请使用 third-party CDN,如 cloudflare、cdnjs 或 unpkg。将这些库添加为基于 CDN 的 UMD 包。
为此,您需要将这些依赖项添加到通常使用 html-webpack-plugin
.
index.html
文件中
<!-- index.html -->
<script crossorigin src="https://unpkg.com/react@18/umd/react.production.min.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@18/umd/react-dom.production.min.js"></script>
现在,只需告诉 Webpack 不要捆绑这些您已经通过 CDN script
提供的依赖项。使用 Webpack externals 来做到这一点:
// webpack.config.js
module.exports = {
externals: {
'react': 'React',
'react-dom': 'ReactDOM'
},
};
通过这种配置,Webpack 不仅会从捆绑中排除 React,还会加快您的捆绑速度。无论你从 React 库中导入什么,Webpack 都会将其替换为全局 object React
.
然后您可以将此模型扩展到您正在使用的所有稳定库。 使用这种方式的另一个重要优势是,您的用户可能已经访问过其他网站,这些网站会使用相同的 CDN 在他们的浏览器中缓存此特定文件。
要自动化您的工作流程,您可以自定义 Webpack 或任何捆绑器脚本,通过读取依赖项的 packge.json
文件然后生成 <script>
标记来注入这些脚本的确切版本。这意味着您的依赖项版本仍然拥有单一的真实来源。您可以阅读 CDN documentation 以了解它们如何允许您为依赖项构建 CDN URL。