[英]Cache-Control policy for external Next.js Image coming from AWS CloudFront is not efficient for Google Lighthouse
I'm trying to optimize my Next.js app by fixing all the issues reported by Google Lighthouse.我正在尝试通过修复 Google Lighthouse 报告的所有问题来优化我的 Next.js 应用程序。
One of the most important pitfalls it has right now regards to images:它目前在图像方面最重要的陷阱之一:
As per the documentation , Next.js automatically does so for media in the static
folder根据文档,Next.js 自动为
static
文件夹中的媒体执行此操作
Next.js automatically adds caching headers to immutable assets served from /_next/static including JavaScript, CSS, static images, and other media.
Next.js 自动将缓存标头添加到从 /_next/static 提供的不可变资产,包括 JavaScript、CSS、static 图像和其他媒体。
As all of those problematic images are coming from an API, which serves them from AWS CloudFront, I can't find a way to fix the problem.由于所有这些有问题的图像都来自 API,它从 AWS CloudFront 为它们提供服务,所以我找不到解决问题的方法。
I guess adding the suggested Cache-Control
policy in CloudFront may help but I don't know我想在 CloudFront 中添加建议的
Cache-Control
策略可能会有所帮助,但我不知道
1.) If that's the right solution 2.) How to do so in AWS Console 1.) 如果那是正确的解决方案 2.) 如何在 AWS 控制台中这样做
Next.js automatically adds caching headers to immutable assets served from /_next/static including JavaScript, CSS, static images, and other media.
Next.js 自动将缓存标头添加到从 /_next/static 提供的不可变资产,包括 JavaScript、CSS、static 图像和其他媒体。
This is not the case when you are using next export
and deploying a static site to S3 & CloudFront, see unsupported features (although they do not state that explicitly).当您使用
next export
并将 static 站点部署到 S3 和 CloudFront 时,情况并非如此,请参阅不受支持的功能(尽管它们没有 state 明确说明)。 What you can do is set these Cache-Control headers yourself manually with S3 object metadata .您可以做的是使用S3 object metadata自己手动设置这些Cache-Control标头。 This is a preferred way for a next.js app because you can specify the headers for each object separately.
这是 next.js 应用程序的首选方式,因为您可以分别为每个 object 指定标头。
Generally (see Caching best practices & max-age gotchas ) you should add max-age=31536000,public,immutable
directives to the whole _next/static
folder since these will have the hash appended to the file name, thus the cache gets invalidated on every new change.通常(请参阅缓存最佳实践和最大年龄陷阱)您应该将
max-age=31536000,public,immutable
指令添加到整个_next/static
文件夹,因为这些指令会将 hash 附加到文件名,因此缓存在每一个新的变化。
Other than that it's for you to manage & depends on what type of app you're building, but it's common practice to set the HTML documents to public,max-age=0,must-revalidate
(even no-cache,no-store
).除此之外,它由您管理并取决于您正在构建的应用程序类型,但通常的做法是将 HTML 文档设置为
public,max-age=0,must-revalidate
(even no-cache,no-store
). Since you are using CloudFront it's fine to keep them in the edge cache as long as u have a proper invalidation set up.由于您使用的是 CloudFront,因此只要您设置了适当的失效设置,就可以将它们保存在边缘缓存中。
You also might have non-statically imported images with src="<path string>"
, these also won't be exported to the _next/static
folder so if you want to add long max-age
& immutable content
to these you have to manage the versioning/hashing yourself to invalidate properly when the images change.您还可能使用
src="<path string>"
非静态导入图像,这些图像也不会导出到_next/static
文件夹,因此如果您想向这些图像添加long max-age
和immutable content
,您必须自己管理版本控制/散列以在图像更改时正确失效。
Checkout editing object metadata in the Amazon S3 console , to add Cache-Control
headers to _next/static
objects metadata: 在 Amazon S3 控制台检查编辑 object 元数据,将
Cache-Control
标头添加到_next/static
对象元数据:
_next/
directory. _next/
目录左侧的复选框。Cache-Control
for the key and add max-age=31536000,public,immutable
as the value. Cache-Control
并添加max-age=31536000,public,immutable
作为值。_next/static
files metadata recursively, you can verify it by opening a specific file and scrolling down to the metadata section._next/static
文件元数据,您可以通过打开特定文件并向下滚动到元数据部分来验证它。 If you are using AWS CDK you can use multiple BucketDeployment
constructs to specify different Cache-Control
headers for different out
directories (see examples ):如果您使用的是 AWS CDK,则可以使用多个
BucketDeployment
构造来为不同out
目录指定不同Cache-Control
标头(参见示例):
// _next/static - long max-age & immutable content
new s3deploy.BucketDeployment(this, 'BucketDeployment', {
...
sources: [s3deploy.Source.asset('./out', { exclude: [ '/**/*', '!/_next/static/**/*'] })],
cacheControl: [s3deploy.CacheControl.fromString('max-age=31536000,public,immutable')],
...
});
// revalidate everything else
new s3deploy.BucketDeployment(this, 'BucketDeployment', {
...
sources: [s3deploy.Source.asset('./out', { exclude: ['/_next/static/**/*'] })],
cacheControl: [s3deploy.CacheControl.fromString('max-age=0,no-cache,no-store,must-revalidate')],
...
});
I'd also suggest (if using some additional AWS resources and terraform is not an issue) taking a look at this terraform module or very least their image optimizer which can be dropped in as a standalone image optimization loader for the Next.js image component, so you get all the next/image
component benefits (there's also this issue for bunch of other workarounds).我还建议(如果使用一些额外的 AWS 资源并且 terraform 不是问题)看看这个terraform 模块或至少他们的图像优化器,它可以作为 Next.js 图像组件的独立图像优化加载器,所以您将获得所有
next/image
组件的好处(还有许多其他解决方法也存在此问题)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.