使用浏览器缓存

当PageSpeed Insights检测到您的服务器响应不包含明确的缓存标头或某些资源被指定只缓存一小段时间时,就会触发此规则。

概览

如果用户会多次访问您的网站,那么静态资源的浏览器缓存可以节省用户的时间。缓存标头应当应用到所有可缓存的静态资源中,而不仅仅是应用到一小部分静态资源(例如,图片)中。可缓存的资源包括JS和CSS文件、图像文件及其他二进制对象文件(媒体文件和PDF文件等)。通常情况下,HTML不是静态资源,默认情况下不应被视为可缓存资源。您应考虑哪些缓存政策适用于您网站的HTML。

建议

为您的服务器启用浏览器缓存。静态资源应该至少有一周的缓存有效期。广告或小部件这类的第三方资源也应该至少有一天的缓存有效期。对于所有可缓存资源,我们建议您进行以下设置:

  • Expires设为将来日期,至少为一周,最多为一年(我们倾向于设置Expires,而不设置Cache-Control: max-age,因为前者受支持的范围更为广泛)。请勿将其设为超过一年的将来日期,因为这样就违反了RFC准则。
  • 如果您知道资源将具体在何时发生变化,则可以设置较短的过期日期。然而,如果您认为资源“可能将要发生变化”,但又不知道具体时间,则应设置较长的过期日期,并使用网址指纹(如下所述)。

Expires和Cache-Control: max-age标头

这些标头用于指定相应时间段,浏览器可在指定的这段时间内使用已缓存的资源,而无需查看网络服务器是否提供了新版资源。这些缓存标头功能强大,没有任何应用条件限制。在设置这些标头并下载资源后,浏览器不会为资源发出任何GET请求,除非过期日期到期或达到时间最大值,亦或是用户清除了缓存。

Last-Modifed和ETag标头

这些标头可用于指定浏览器应如何确定用于缓存的文件是否相同。在Last-Modified标头中指定的是日期,而在ETag标头中指定的则可以是唯一标识资源的任意值(通常为文件版本或内容哈希值)。Last-Modified是功能“较弱”的缓存标头,因为浏览器会使用试探法来确定是否需要从缓存中抓取内容。

借助这些标头,浏览器可以通过在用户明确重新加载页面时发出条件式GET请求,有效地更新其已缓存资源。除非您在服务器端更改资源,否则条件式GET请求不会返回完整的响应,因此相较于完整GET请求,此类请求的延迟较小。

我应使用哪个缓存标头?

对于所有可缓存资源,指定一个ExpiresCache-Control max-age以及一个Last-ModifiedETag至关重要。您没必要同时指定ExpiresCache-Control: max-age;或同时指定Last-ModifiedETag

使用网址指纹

对于偶尔发生变化的资源,我们可以让浏览器缓存相应的资源,直到该资源在服务器上出现变化,而服务器则在此时通知浏览器有新版本可用。我们可以通过为每个版本的资源指定一个唯一网址来实现这一目的。例如,假定我们有一个名为“my_stylesheet.css”的资源。我们可以将文件重命名为“my_stylesheet_fingerprint.css”。当资源发生变化时,其指纹就会发生变化,对应的网址也会随之更改。网址一经更改,系统就会强制浏览器重新抓取资源。通过指纹,我们甚至可以为变化更为频繁的资源设置将来的过期日期。

指纹识别的常用方法是使用对文件内容的哈希值进行编码的128位十六进制数。

另一个策略是直接为新版应用创建新版目录,然后为版本目录中的各个版本放置所有资源。这样做的缺点是,如果各个版本中的资源未发生变化,则其网址将仍会更改以强制重新下载。使用内容哈希值不会遇到该问题,但这种方法稍微复杂一些。