在 Vite 构建中添加 CDN 缓存

Avatar of Adam Rackis
Adam Rackis

DigitalOcean 为您旅程的每个阶段提供云产品。 立即开始使用 200 美元的免费额度!

内容分发网络(CDN)允许您改进网站静态资源的交付,最显著的是通过 CDN 缓存。 它们通过从边缘位置(遍布全球)提供您的内容来实现这一点。 当用户浏览您的网站,并且您的网站请求 CDN 中的资源时,CDN 会将该请求路由到最近的边缘位置。 如果该位置拥有请求的资源(来自该用户的先前访问或其他用户),则将从缓存中提供内容。 如果没有,CDN 将从您的底层域请求内容,将其缓存并提供。

无数的 CDN 可供选择,但对于这篇文章,我们将使用 AWS CloudFront。 我们将了解如何设置一个 CloudFront 分发,以提供我们网站的所有资源:JavaScript 文件、CSS 文件、字体文件等。 然后,我们将了解如何将其集成到 Vite 构建中。 如果您想了解有关 Vite 的更多信息,我在这里有一个介绍

设置 CloudFront CDN 分发

让我们直接开始设置我们的 CloudFront CDN 分发。

对于任何严肃的项目,您都应该使用代码设置您的无服务器基础设施,使用诸如 Serverless 框架或 AWS 的 CDK 之类的东西。 但为了简单起见,在这里,我们将使用 AWS 控制台设置我们的 CDN。

转到 CloudFront 主页。 在右上方,您应该会看到一个橙色的按钮,用于创建新的分发。

CloudFront CDN Distributions screen.

创建屏幕有很多选项,但在大多数情况下,默认选择就可以了。 首先也是最重要的是,添加资源所在的域。

CloudFront CDN distribution creation screen.

接下来,向下滚动并找到 **响应标头策略** 下拉菜单,然后选择“CORS-With-Preflight”。

CloudFront response headers settings.

最后,单击底部的 **创建分发** 按钮,希望您会看到您的新分发。

CloudFront CDN distribution overview screen.

将 CDN 与 Vite 集成

我们的 CDN 设置好并准备提供我们的文件是一回事。 但我们的网站实际 *知道* *如何* 从我们的 CDN 请求它们又是另一回事。 我将逐步介绍与 Vite 集成的过程,但其他构建系统(如 webpack 或 Rollup)也类似。

当 Vite 构建我们的网站时,它会维护一个网站各个部分导入的所有 JavaScript 和 CSS 文件的“图”,并注入适当的 <script> 标签、<link> 标签或 import() 语句来加载所需的内容。 我们需要做的是告诉 Vite 在生产环境中从我们的 CDN 请求这些资源。 让我们看看如何操作。

打开您的 vite.config.ts 文件。 首先,我们需要知道我们是在实时网站(生产)还是在开发(开发)环境中。

const isProduction = process.env.NODE_ENV === "production"; 

这之所以有效,是因为当我们运行 vite build 时,Vite 会设置此环境变量,这是我们在生产中执行的操作,而不是在具有热模块重新加载的开发模式中。

接下来,我们告诉 Vite 从我们的 CDN 获取我们的资源,如下所示,设置配置对象的 base 属性

export default defineConfig({
  base: isProduction ? process.env.REACT_CDN : "",

请务必将您的 REACT_CDN 环境变量设置为 CDN 的位置,在本例中,将是我们的 CloudFront 分发的位置。 我的看起来像这样(但不完全一样)

https://distributiondomainname.cloudfront.net

注意您的 VitePWA 设置!

作为最后的清理工作,如果您碰巧正在使用 VitePWA 插件,请确保像这样重置您的 base 属性

VitePWA({
  base: "/",

否则,您的 web.manifest 文件将具有无效设置并导致错误。

让我们看看 CDN 的工作原理

一切设置完成后,浏览到您的网站,并检查脚本或 CSS 文件的任何网络请求。 首先,协议应该是 h2。

Showing the assets served via CDN caching in DevTools. Each file name includes a unique random string of letters and numbers.

从那里,您可以查看其中任何一个文件的响应标头,您应该会在其中看到一些 CloudFront 数据

Screenshot of a response header.

缓存清除

如果不提及缓存清除,就很难谈论 CDN。 像 CloudFront 这样的 CDN 具有手动“弹出”缓存中项目的功

因此,Vite 可能会在构建期间将 home.js 文件转换为 home-abc123.js,但如果您更改该文件并重新构建,它可能会变为 home-xyz987.js。 这样做很好,因为它会“破坏缓存”,并且新构建的文件不会被缓存,因此 CDN 将必须转向我们的主机域以获取实际内容。

其他静态资源的 CDN 缓存

JavaScript、CSS 和字体文件并不是唯一可以从 CDN 缓存中受益的资源类型。 如果您有一个 S3 存储桶用于提供 *图像*,请考虑也为其设置 CloudFront 分发。 有专门针对 S3 的选项,这使得创建它变得轻而易举。 您不仅可以获得相同的边缘缓存,还可以获得 HTTP/2 响应,而 S3 *不* 提供 HTTP/2 响应。

高级 CDN 实践

在这里集成 CDN 相对简单,但我们只享受了其潜在优势的一小部分。 现在,用户将浏览到我们的应用程序,我们的服务器将提供我们的根 HTML 文件,然后用户的浏览器将连接到我们的 CDN 以开始下载所有静态资源。

更进一步,我们希望从 CDN 提供我们的整个网站。 这样,它可以根据需要与我们的 Web 服务器通信以获取非静态和非缓存资源。

结论

CDN 是提高网站性能的好方法。 它们开箱即用地提供边缘缓存和 HTTP/2。 不仅如此,它们还易于设置。 现在,您掌握了一种新的工具,可以设置 CDN 并将其与 Vite 集成。