我正在使用 SST 测试 NextJS 托管,因此我部署了一个简单的 nextJS 应用程序,仅呈现此静态页面:
// src/pages/index.tsx
function Home() {
return <h1>Hello</h1>;
}
export default Home;
这是堆栈代码:
import { SSTConfig } from "sst";
import { NextjsSite } from "sst/constructs";
export default {
config(_input) {
return {
name: "test-next",
region: "sa-east-1",
};
},
stacks(app) {
app.stack(function Site({ stack }) {
const site = new NextjsSite(stack, "site");
stack.addOutputs({
SiteUrl: site.url,
});
});
},
} satisfies SSTConfig;
一切工作正常,但我注意到的一件事是所有页面响应标头都将标头
X-Cache
设为 Miss from Cloudfront
。另一个奇怪的事情是,对 CloudFront URL 的所有请求都会命中服务器端渲染 NextJS 页面的 lambda 函数,我知道这是因为名为 siteServerFunction
的云监视日志组在每次发出请求时都会记录一个调用。
问题是这个页面没有使用SSR,它是一个应该在编译时生成、由s3提供服务并由CloudFront缓存的页面。那么,到底发生了什么? SST支持不静态站点生成吗?
所以这可能只是有点混乱。我在 https://campaign.tools 上有完全相同的设置。它也是一个通过 SST 部署为
StaticSite
的 Next.js 站点。
让我帮助您了解正在发生的过程......
当 SST 生成
StaticSite
时,它会自动设置 CloudFront 分配缓存。这些可以通过 assets.fileOptions
配置对象中的 StaticSite
手动覆盖。 文档显示默认行为是缓存所有 JS/CSS 文件而不缓存 HTML 文件:
assets.fileOptions?
类型:数组
默认:HTML 文件无缓存控制,JS/CSS 文件有 1 年缓存控制。
话虽如此,您会从 CloudFront 获得缓存未命中,或者至少看起来是这样。对于 JS 和 CSS 文件,这很好,因为这些文件已缓存在您的客户端上。如果您查看 JS/CSS 文件,您将看到以下标题:
X-Cache: Miss from cloudfront
看起来我们没有得到任何 CloudFront 缓存命中;但是,如果您查看
Status Code
部分中的 General
,我希望您会发现以下内容:
Status Code: 200 OK (from disk cache)
如果是这种情况,则意味着您的客户端对 CloudFront 的第一次调用失败了,但由于
Cache-Control
标头,它随后在浏览器中缓存了该请求。您应该看到该标头的以下值:
Cache-Control: max-age=31536000,public,immutable
如果是这种情况,那么您的客户端只是缓存了 CloudFront 的第一个“未命中”,并且看起来您总是无法命中缓存。如果需要,请单击客户端网络选项卡中的
Disable cache
并重新加载站点。您现在应该开始看到缓存命中!但别担心,它总是被缓存的:D