css中的背景图像没有被缓存

gcmastyq  于 2023-04-08  发布在  其他
关注(0)|答案(4)|浏览(283)

我有一些通过React.createElement动态渲染内容的react代码。因此,css通过对象应用。动态生成中的元素可以有背景图像,指向公共aws S3桶。
似乎每次我的组件重新渲染时,都会再次从S3中获取背景图像。这会延迟页面渲染。我在所有对象上设置了S3元数据的Cache-Control。下面是背景图像加载的请求和响应头-
响应标头-

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

请求标头-

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

我可以看到在网络选项卡中的图像被加载多次,它也显示数据传输正在做的每一次.我在这里做错了什么?有人可以请帮助找到根本原因.谢谢.

yquaqz18

yquaqz181#

这可能是一个被遗忘的“禁用缓存”选项选择在网络选项卡中的开发工具?因为它似乎服务器响应与正确类型的缓存头。

polhcujo

polhcujo2#

如果图像经过优化,并且不是很大,使用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上的缓存
  • 更好地控制缓存头
  • 隐藏你s3真实的网址
huwehgph

huwehgph3#

您看到网络请求的原因可能是因为您在请求中使用了Cache-Control: no-cache标头。
如图所示:
no-cache response指令指示响应可以存储在缓存中,但是响应必须在每次重用之前通过源服务器进行验证,即使该高速缓存与源服务器断开连接。
缓存控制:无缓存
如果你想让缓存在重用存储的内容时始终检查内容更新,可以使用no-cache指令。它要求缓存向源服务器重新验证每个请求。
注意,no-cache并不意味着“不缓存”。no-cache允许缓存存储响应,但要求它们在重用之前重新验证它。如果你想要的“不缓存”的含义实际上是“不存储”,那么no-store就是要使用的指令。
请参见:https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control#response_directives
下面是当资产从验证请求返回304 Not Modified(来自S3)时,在我的网络选项卡上对缓存资产的完整请求的样子。

66bbxpm5

66bbxpm54#

虽然我也在开发工具中选中了“Disable cache”选项,但我必须发送{ cache: 'force-cache' }作为init参数。
例如:

fetch(someUrl, { cache: 'force-cache' })

相关问题