如果用户会多次访问您的网站,那么静态资源的浏览器缓存可以节省用户的时间。缓存标头应当应用到所有可缓存的静态资源中,而不仅仅是应用到一小部分静态资源(例如,图片)中。可缓存的资源包括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请求,此类请求的延迟较小。
我应使用哪个缓存标头?
对于所有可缓存资源,指定一个Expires或Cache-Control max-age以及一个Last-Modified或ETag至关重要。您没必要同时指定Expires和Cache-Control: max-age;或同时指定Last-Modified和ETag。
使用网址指纹
对于偶尔发生变化的资源,我们可以让浏览器缓存相应的资源,直到该资源在服务器上出现变化,而服务器则在此时通知浏览器有新版本可用。我们可以通过为每个版本的资源指定一个唯一网址来实现这一目的。例如,假定我们有一个名为“my_stylesheet.css”的资源。我们可以将文件重命名为“my_stylesheet_fingerprint.css”。当资源发生变化时,其指纹就会发生变化,对应的网址也会随之更改。网址一经更改,系统就会强制浏览器重新抓取资源。通过指纹,我们甚至可以为变化更为频繁的资源设置将来的过期日期。
指纹识别的常用方法是使用对文件内容的哈希值进行编码的128位十六进制数。
另一个策略是直接为新版应用创建新版目录,然后为版本目录中的各个版本放置所有资源。这样做的缺点是,如果各个版本中的资源未发生变化,则其网址将仍会更改以强制重新下载。使用内容哈希值不会遇到该问题,但这种方法稍微复杂一些。