css 中的背景图片未被缓存

Background images in css are not getting cached

我有一些通过 React.createElement 动态呈现内容的反应代码。因此,css 通过 object 应用。该动态生成中的元素可以有背景图像,指向 public aws S3 存储桶。

似乎每次我的组件 re-render,背景图像都从 S3 再次获取。这会延迟页面呈现。我在所有 objects 上设置了 Cache-Control 的 S3 meta-data。这是背景图片加载的请求和响应 headers -

回应header-

Accept-Ranges: bytes
Cache-Control: public, max-age=604800
Content-Length: 52532
Content-Type: application/octet-stream
Date: Sun, 06 Feb 2022 05:57:32 GMT
ETag: "f29655808a5f80627d9ea7f44058a5e3"
Last-Modified: Sun, 06 Feb 2022 05:55:10 GMT
Server: AmazonS3
x-amz-meta-filetype: IMAGE

请求Header-

Accept: image/avif,image/webp,image/apng,image/svg+xml,image/*,*/*;q=0.8
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.9,hi;q=0.8
Cache-Control: no-cache
Connection: keep-alive
Host:  <bucket-name>s3.amazonaws.com
Pragma: no-cache
Referer: https://<my-domain>.com/
sec-ch-ua: " Not;A Brand";v="99", "Google Chrome";v="97", "Chromium";v="97"
sec-ch-ua-mobile: ?0
sec-ch-ua-platform: "Linux"
Sec-Fetch-Dest: image
Sec-Fetch-Mode: no-cors
Sec-Fetch-Site: cross-site
User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.71 Safari/537.36

我可以在“网络”选项卡中看到图像被多次加载,并且它还显示每次都在进行数据传输。我在这里做错了什么?有人可以帮助找到根本原因。谢谢

您看到网络请求的原因可能是因为您在请求中使用了 Cache-Control: no-cache header。

如此处所示:

The no-cache response directive indicates that the response can be stored in caches, but the response must be validated with the origin server before each reuse, even when the cache is disconnected from the origin server.

Cache-Control: no-cache

If you want caches to always check for content updates while reusing stored content, no-cache is the directive to use. It does this by requiring caches to revalidate each request with the origin server.

Note that no-cache does not mean "don't cache". no-cache allows caches to store a response but requires them to revalidate it before reuse. If the sense of "don't cache" that you want is actually "don't store", then no-store is the directive to use.

看这里:https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control#response_directives

这是当资产 returns 304 Not Modified 来自验证请求时,缓存资产的完整请求在我的网络选项卡上的样子。 (来自 S3)这是在 background: url 上下文中。

可能是在开发工具的网络选项卡中忘记选择了“禁用缓存”选项?因为服务器似乎以正确类型的缓存响应 headers.

如果图像经过优化并且不是很大,使用 base64 数据 url 是一个很好的解决方案。

const getBase64FromUrl = async (url) => {
  const data = await fetch(url);
  const blob = await data.blob();
  return new Promise((resolve) => {
    const reader = new FileReader();
    reader.readAsDataURL(blob); 
    reader.onloadend = () => {
      const base64data = reader.result;   
      resolve(base64data);
    }
  });
}

const image = getBase64FromUrl('the image url')

创建元素时您可以使用

background-image: `url(${image})`;

此外,我们很少直接从 S3 提供服务,您可能应该使用 cloudfront 作为代理

  • 减少获取请求
  • 降低带宽费用
  • 缓存在 cdn
  • 更好地控制缓存headers
  • 隐藏你的 s3 真实 url