简体   繁体   English

来自 AWS CloudFront 的外部 Next.js 图像的缓存控制策略对于 Google Lighthouse 效率不高

[英]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-ageimmutable content ,您必须自己管理版本控制/散列以在图像更改时正确失效。

With AWS Console使用 AWS 控制台

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对象元数据:

  1. Open the Amazon S3 console and your bucket.打开 Amazon S3 控制台和您的存储桶。
  2. Select the check box to the left of the _next/ directory. Select _next/目录左侧的复选框。
  3. On the Actions menu, choose Edit actions, and choose Edit metadata.在操作菜单上,选择编辑操作,然后选择编辑元数据。
  4. Choose Add metadata.选择添加元数据。
  5. For metadata Type, select System-defined.对于元数据类型,select 系统定义。
  6. Select Cache-Control for the key and add max-age=31536000,public,immutable as the value. Select 键的Cache-Control并添加max-age=31536000,public,immutable作为值。
  7. When you are done, hit Save Changes and Amazon S3 should edit all the _next/static files metadata recursively, you can verify it by opening a specific file and scrolling down to the metadata section.完成后,点击保存更改,Amazon S3 应该递归地编辑所有_next/static文件元数据,您可以通过打开特定文件并向下滚动到元数据部分来验证它。

With CDK带CDK

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')],
  ...
});

Improving without Vercel不使用 Vercel 进行改进

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.

相关问题 Cloudfront 缓存控制标头丢失 - Cloudfront cache-control headers missing 即使使用缓存控制,来自云端的 RefreshHit:max-age=0,无存储 - RefreshHit from cloudfront even with cache-control: max-age=0, no-store EC2 缓存上的 AWS Next.js - AWS Next.js on EC2 caching AWS CloudFront:来自源的字体已被跨源资源共享策略阻止加载 - AWS CloudFront: Font from origin has been blocked from loading by Cross-Origin Resource Sharing policy 如何将 next.js + mongo 应用程序部署到 AWS(或 G Cloud 等任何其他服务)? - How to deploy a next.js + mongo app to AWS (or any other service like G Cloud)? AWS ECS + Fargate GraphQL 请求上的 Next.js CSR 不起作用 - Next.js CSR on AWS ECS + Fargate GraphQL request doesn't work 为 CloudFront 创建 AWS FMS 策略时出现内部异常 - Internal Exception while creating AWS FMS Policy for CloudFront Firebase 托管“重写”以访问 Google Cloud Run 上的 Next.js 应用程序 - Firebase Hosting "rewrites" to Access Next.js App on Google Cloud Run 通过 Next.js(使用 Typescript)应用程序调用 Google Cloud Function 的正确方法是什么? - What Is The Right Way to Call A Google Cloud Function via A Next.js (with Typescript) App? 如何使用 next.js 在每“n”个帖子后在 Feed 中添加 Google Ads - How to add Google Ads in a Feed after every 'n' number of Post using next.js
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM