【问题标题】:Does webpack splitting good for saving AWS cost?webpack 拆分对节省 AWS 成本有好处吗?
【发布时间】:2022-06-21 10:22:12
【问题描述】:

我们的网站是用沉重的node_modules构建的。
许多重包导致重 node_modules 并最终影响 AWS 上的重成本。
因此,我们正在尝试减少总捆绑包大小以降低一些成本
我发现,通过使用 webpack 拆分代码,我们可以拥有更多但更小的包。不过,整体大小并没有太大变化。

我想知道的是,使用 webpack 拆分代码是否可以节省一些 AWS 成本?
抱歉,这个问题很糟糕,但这是我现在能想到的。
任何好主意都会非常有帮助,谢谢。

【问题讨论】:

  • 您使用的是 cloudfront+S3 还是 S3 网站功能?你能描述一下你的缓存策略吗?
  • @MisterSmith 是的,我们正在使用 cloudfront 和 s3。我们建立我们的网站并将它们放在 S3 中,由云端交付。我正在处理的问题是保存在 s3 中的资产会导致高昂的成本。
  • 如果 S3 是您使用 S3+CloudFront 的最大成本,我会说您需要先查看您的缓存策略,然后再查看任何特定优化以获得最大收益。检查缓存命中/未命中的 Cloudfront 统计信息,并确认将哪些默认缓存标头应用于您的静态资源。听起来您的静态资产缓存时间不够长 - 如果是这样,您对 WebPack 的更改可能不会对您的成本产生太大影响。
  • @MisterSmith 谢谢!这将是节省一些成本的好方法!

标签: amazon-web-services amazon-s3 webpack node-modules


【解决方案1】:

这是一个复杂的话题,也是同样开放式的问题!为了回答这个问题,我将做一些假设:

  • 节省 AWS 成本意味着减少捆绑包大小,从而节省传出带宽成本。
  • 正在构建的应用程序是 100% SPA 即完全客户端。服务器端优化很快就会变得非常复杂。

开箱即用,Webpack 会将所有内容捆绑到一个大文件/包中。它包含您自己的代码以及来自第三方库的代码。 这里的基本思想是第三方代码很少更改,而我们自己的代码经常更改。

因此,我们可以使用 Webpack 将我们的代码拆分为两个不同的夹头,使用 SplitChunksPlugin。一个用于我们自己的代码,另一个用于第三方代码,即来自node_modules 文件夹的代码;让我们称之为供应商捆绑。现在,只要您的 node_modules 文件夹保持不变,即您的锁定文件 - package-lock.json 文件保持不变,它就会始终为第三方代码生成具有完全相同内容的相同包。

接下来的想法是您可以简单地获取此供应商捆绑包并将其上传到 CDN,然后通过 CDN 使用。 CDN 和浏览器会发挥它们的缓存魔法,用户几乎不需要每次都下载这个文件。 CDN 将使用ETag 和/或cache-control 标头来实现这一点,浏览器将使用它。

然而,实际情况有所不同。当你有太多依赖或者使用 dependabot 更新依赖时,你会经常更新你的锁文件。这意味着在每次构建时都会生成一个新的供应商捆绑包,即使存在单个字节的差异。 Webpack 生成的 hash id 会有所不同。而在其他情况下,您导入依赖项的方式也可能会更改生成的包内容,从而导致不同的包。

因此,在架构上,我们通过使用 CDN 来更好地捆绑供应商。第一步是区分稳定的第三方模块和经常更新的第三方模块。例如,考虑reactreact-domrxjs 等。这些不经常更新。对于这些库,请使用 cloudflare、cdnjs 或 unpkg 等第三方 CDN。将这些库添加为基于 CDN 的 UMD 包。

为此,您需要将这些依赖项添加到您的 index.html 文件中,该文件通常使用 html-webpack-plugin 生成。

<!-- 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 都会将其替换为全局对象 React

然后您可以将此模型扩展到您正在使用的所有稳定库。 使用这种方式的另一个重要优势是,您的用户可能已经访问过其他网站,这些网站会使用相同的 CDN 在他们的浏览器中缓存此特定文件。

要自动化您的工作流程,您可以自定义 Webpack 或任何捆绑程序脚本,以通过读取您的依赖项的 packge.json 文件然后生成 &lt;script&gt; 标记来注入具有精确版本的这些脚本。这意味着您的依赖项版本仍然有单一的事实来源。您可以阅读 CDN documentation 以了解它们如何允许您为依赖项构建 CDN URL。

【讨论】:

  • 感谢您的详细解答。 CDN 将是一个很好的解决方案!
猜你喜欢
  • 1970-01-01
  • 2011-09-06
  • 2017-05-10
  • 2023-01-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-07-13
  • 1970-01-01
相关资源
最近更新 更多