1-优化缓存

原文:http://code.google.com/intl/zh-CN/speed/page-speed/docs/caching.html

 

大多数网页(包括网页引用的资源,例如CSS文件、图片文件,JavaScript文件等)变化的频度非常高。这些资源都需要花时间从网上下载,他 们会增加网页加载的时间。HTTP缓存允许这些资源被浏览器或代理存储或者缓存。一旦资源被缓存,随后访问页面时,浏览器或代理将直接找本地缓存的副本而不是再次下载。因此使用缓存是双赢的:节省了往返时间,减少了大量HTTP去请求需要的资源,同时大幅缩减响应负荷的总体尺寸。缓存除了可以戏剧性的缩减多数用户访问页面的加载时间之外,还能极大减小带宽和站点主机的费用。

  1. 利用浏览器的缓存(Leverage browser caching
  2. 利用代理的缓存(Leverage proxy caching



利用浏览器的缓存


概览

在HTTP头部为静态资源设置明确过期日期或最大有效期,这些设置将指导浏览器首先从本地磁盘上(而不是通过网络)加载这些资源。


详情

HTTP/S支持浏览器本地缓存静态资源。一些较新的浏览器(例如IE7,谷歌浏览器Chrome等)使用启发式规则确定多久缓存所有的资源,而不依赖头部明确的缓存设置。其他较老的浏览器可能依赖头部的缓存设置去缓冲区拿取资源;而且有些浏览器可能不会缓存任何通过SSL发送的资源。

为了让所有浏览器获得缓存的好处,我们推荐配置web服务器明确设置缓存头部,并应用给所有可以缓存的静态资源,而不仅仅是小的子设置(例如图片)。可缓存的资源包括JS和CSS文件、图片文件,以及其他二进制对象的文件(例如媒体文件,PDF文件,Flash文件等)。通常,HTML不是静态的,并且也认为是不可缓存的。

 

HTTP/1.1 提供下列缓存响应头(caching response headers):

  • Expires and Cache-Control : max-age 有效期和缓冲控制:最大时限 详细指定资源的“保鲜期”, 即,浏览器能使用该缓存的时间期限。在这个期限内浏览器会直接使用缓存,而不会查看web服务器是否有新版本可用。它们是“强”缓存头,被无条件应用的, 也就是说,一旦它们被设置、而且资源被下载,没有到过期时刻,浏览器不会发出任何GET请求。
  • Last-Modified and ETag (最后修改和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


推荐

积极的为所有静态资源设置缓存头
对所有可缓存的资源,我们推荐如下设置:
  • 设置不小于最小的一个月、不大于一年的 Expires 。(与设置 Cache-Control: max-age 相比,设置 Expires 更好,因为 Expires 能得到更广泛的支持。)不要设置超过一年的 Expires ,这样做是违反 RFC(Request For Comments 请求注解)准则的。

    如果你知道资源更新的确切时间,可以设置一个较短的过期时间。但是,如果你仅仅知道它“可能很快更新”,并不知道到底什么时候更新,你应当设置一个较长的过期,并使用 URL 指纹(具体描述见下)。积极设置缓存不会“污染”浏览器的缓存:据我们所知,所有浏览器都会依据最近最少使用算法清理自己的缓冲;我们还没有发现有浏览器等到资源过期才清理缓存。

  • 为最新更新的资源设置 Last-Modified 日期。如果之前设置的 Last-Modified 日期很长,浏览器不会去获取更新的资源。

使用指纹动态启用缓存
对偶尔更新的资源,当服务器更新资源时,可以让服务器告诉浏览器有新的资源可用,让浏览器去缓存它。你可以通过在资源的URL(即:文件路径)嵌入指纹的方式实现这个功能。资源更新时,资源的指纹随之更新,于是资源的 URL也随之更新了。一旦资源的URL更新,浏览器被迫重新获取该资源。指纹允许你设置延迟到未来很久的有效期,甚至可以设置经常更新的资源。当然,这项技术要求所有引用该资源的网页都知道该资源的指纹URL。至于这样做是否弹性欠佳,取决于页面的编码。

为IE浏览器设置正确的 Vary 头
IE浏览器不缓存任何标记了 Vary 的头部或域的资源,除非被 Accept-Encoding User-Agent 标记。为了确保这些资源被 IE 缓存,请务必去除来自 Vary 头的域,如果有可能的话请直接删除 Vary 头。

在Firefox中避免URL冲突
Firefox 的磁盘缓存哈斯函数会与URL产生碰撞,仅有细微的差别,换句话说只限于8个字符范围的差异(Firefox disk cache hash functions can generate collisions for URLs that differ only slightly, namely only on 8-character boundaries.)。如果几个资源被哈希为相同的键(Key),其中仅有一个资源得到磁盘缓存;剩下的拥有同样键的资源会在Firefox重启的时候重新被获取。因此,只要能确保你的应用程序产生的URL中有超过8个字符不同,使用指纹或者其他程序产生资源文件的URL能最大程度的提高缓存的命中率,避免Firefox哈希冲突。

Firefox 中用 Cache control: public 直接启用 HTTPS 缓存
有些版本的 Firefox 即使在其他的缓冲头部设置了有效期,也需要在头部设置 Cache control: public ,为了使通过 SSL 发送的资源文件也缓存在磁盘上。虽然这个头部通常由代理服务(见下文描述)启用缓存,代理不能缓存任何通过HTTPS传送的内容,所以为HTTPS资源设置这样的头部一般比较安全。


例子

下面这个样式表用来显示登录用户的日历。google 日历就在样式文件名中嵌入了一个指纹:calendar/static/fingerprint_key doozercompiled.css,这个指纹键是一个128位的十六进制数。下面是当时的截屏(来自 Page Speed的 Show Resources 面板),这里的指纹是 82b6bc440914c01297b99b4bca641a5d:

Doc: Web 性能最佳实践 - 优化缓存 - 小青 - 网上营销

对指纹机制,该服务器设置 Expires 头的有效期为一年(原文:The fingerprinting mechanism allows the server to set the Expires header to exactly one year ahead of the request date)。Last-Modified 头标识文件最后一次修改时间(原文:Last-Modified header to the date the file was last modified)。Cache-Control: max-age 头是3153600(原文:Cache-Control: max-age header to 3153600)。每当文件内容发生变化,比如在有效期之前被修改,或者达到最大时限,或者指纹有变化(因此URL也变化了)都会导致客户端重新下载该文件。


附加资源



利用代理缓存


概览

静态资源可以利用HTTP头部的公开缓存,允许浏览器从附近的代理下载资源,而不必从遥远的原始服务器上下载它们。


细节

除了浏览器缓存,HTTP 还提供代理缓存。代理缓存将静态资源缓存在公共的web代理服务器上,特别是ISP的服务器。也就是说,即使第一次访问你站点的用户也能从缓存中获益:只要其他用户通过这个代理访问过那个静态资源,这个资源对任何其他通过同样代理访问的其他用户来说都是可用的。由于这些地点可能比你的服务器更接近网络用户,所以代理能显著缩减网络延迟。同样的,如果启用代理缓存有效,就是给你免费的网站托管,因此来自代理缓存的响应根本不占用你服务器的带宽。

使用 Cache-control: public 头除了可以声明资源被浏览器缓存外,还可以声明被公共web代理缓存。除了一些例外(下面将描述),你应当为你的web服务器配置这样的头以公开(public )可缓存的资源。


建议

在URL中,不要声明带有静态资源的查询字串
大多数代理,主要是Squid 3.0 及以上版本,即使响应中出现 Cache-control: public 头也不缓存URL中带有“?”的资源。要让代理缓存这些资源,得删除指向静态资源上的查询串,将这些参数编码到文件名中。

不要让代理缓存那些设置了cookies的资源
设置这样的头是为了在多个用户之间有效的公开共享资源,也就是说这些资源的cookies也是可以共享的。然而许多代理并不实际缓存带有cookie头设置的资源。因此最好完全避免这样的风险:设置 Cache-Control 头为私有的( private )或者让不含cookie 的域( from a cookieless domain )提供这些资源 的服务。

注意代理缓存 JS 和 CSS 文件的问题
有些公共代理服务器有这样的缺陷:他们不去理会响应的 Content-Encoding 头。结果这些压缩包传到客户端浏览器后不能正确解压。因为这些文件在你的服务器上可能是用 gzipped 格式压缩的,为确保客户端能正确读这些文件,请执行以下任何一个操作:
  • 设置 Cache-Control 头为私有的(private )。这将完全禁止代理缓存这些资源。如果你的应用在全球有多个驻留地(multi-homed),而且本地用户很少依赖代理缓存,这就是一个比较合适的设置。
  • 设置 Vary: Accept-Encoding 响应头。它将指示代理给同一份资源缓存两个版本:一个是压缩的,一个是未压缩的。依据客户端请求的头传送响应版本。对于只有一个驻留地的应用,以及依赖公共代理的本地用户来说,这是一个不错的选择。




译者主页 www.our3w.com/ddm/
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值