web性能优化 HTTP 缓存

经过网络获取内容既速度缓慢又开销巨大。较大的响应须要在客户端与服务器之间进行屡次往返通讯,这会延迟浏览器得到和处理内容的时间,还会增长访问者的流量费用。所以,缓存并重复利用以前获取的资源的能力成为性能优化的一个关键方面。css

好在每一个浏览器都自带了 HTTP 缓存实现功能。您只须要确保每一个服务器响应都提供正确的 HTTP 标头指令,以指示浏览器什么时候能够缓存响应以及能够缓存多久。git

注:若是您在应用中使用 Webview 来获取和显示网页内容,可能须要提供额外的配置标志,以确保 HTTP 缓存获得启用、其大小根据用例进行了合理设置而且缓存将持久保存。务必查看平台文档并确认您的设置!github

这里写图片描述

当服务器返回响应时,还会发出一组 HTTP 标头,用于描述响应的内容类型、长度、缓存指令、验证令牌等。例如,在上图的交互中,服务器返回一个 1024 字节的响应,指示客户端将其缓存最多 120 秒,并提供一个验证令牌(“x234dff”),可在响应过时后用来检查资源是否被修改。浏览器

经过 ETag 验证缓存的响应

  • 服务器使用 ETag HTTP 标头传递验证令牌。
  • 验证令牌可实现高效的资源更新检查:资源未发生变化时不会传送任何数据。

假定在首次获取资源 120 秒后,浏览器又对该资源发起了新的请求。首先,浏览器会检查本地缓存并找到以前的响应。遗憾的是,该响应现已过时,浏览器没法使用。此时,浏览器能够直接发出新的请求并获取新的完整响应。不过,这样作效率较低,由于若是资源未发生变化,那么下载与缓存中已有的彻底相同的信息就毫无道理可言!缓存

这正是验证令牌(在 ETag 标头中指定)旨在解决的问题。服务器生成并返回的随机令牌一般是文件内容的哈希值或某个其余指纹。客户端不须要了解指纹是如何生成的,只需在下一次请求时将其发送至服务器。若是指纹仍然相同,则表示资源未发生变化,您就能够跳过下载。性能优化

这里写图片描述

在上例中,客户端自动在“If-None-Match” HTTP 请求标头内提供 ETag 令牌。服务器根据当前资源核对令牌。若是它未发生变化,服务器将返回“304 Not Modified”响应,告知浏览器缓存中的响应未发生变化,能够再延用 120 秒。请注意,您没必要再次下载响应,这节约了时间和带宽。服务器

做为网络开发者,您如何利用高效的从新验证?浏览器会替咱们完成全部工做:它会自动检测以前是否指定了验证令牌,它会将验证令牌追加到发出的请求上,而且它会根据从服务器接收的响应在必要时更新缓存时间戳。咱们惟一要作的就是确保服务器提供必要的 ETag 令牌。检查您的服务器文档中有无必要的配置标志。markdown

提示:HTML5 Boilerplate 项目包含全部最流行服务器的配置文件样例,其中为每一个配置标志和设置都提供了详细的注解。在列表中找到您喜好的服务器,查找合适的设置,而后复制/确认您的服务器配置了推荐的设置。网络

Cache-Control

  • 每一个资源均可经过 Cache-Control HTTP 标头定义其缓存策略
  • Cache-Control 指令控制谁在什么条件下能够缓存响应以及能够缓存多久。

从性能优化的角度来讲,最佳请求是无需与服务器通讯的请求:您能够经过响应的本地副本消除全部网络延迟,以及避免数据传送的流量费用。为实现此目的,HTTP 规范容许服务器返回 Cache-Control 指令,这些指令控制浏览器和其余中间缓存如何缓存各个响应以及缓存多久。函数

Cache-Control 标头是在 HTTP/1.1 规范中定义的,取代了以前用来定义响应缓存策略的标头(例如 Expires)。全部现代浏览器都支持 Cache-Control,所以,使用它就够了。

这里写图片描述

  1. no-cache”和“no-store” “no-cache”表示必须先与服务器确认返回的响应是否发生了变化,而后才能使用该响应来知足后续对同一网址的请求。所以,若是存在合适的验证令牌 (ETag),no-cache 会发起往返通讯来验证缓存的响应,但若是资源未发生变化,则可避免下载。 相比之下,“no-store”则要简单得多。它直接禁止浏览器以及全部中间缓存存储任何版本的返回响应,例如,包含我的隐私数据或银行业务数据的响应。每次用户请求该资产时,都会向服务器发送请求,并下载完整的响应。

  2. “public”与“private” 若是响应被标记为“public”,则即便它有关联的 HTTP 身份验证,甚至响应状态代码一般没法缓存,也能够缓存响应。大多数状况下,“public”不是必需的,由于明确的缓存信息(例如“max-age”)已表示响应是能够缓存的。 相比之下,浏览器能够缓存“private”响应。不过,这些响应一般只为单个用户缓存,所以不容许任何中间缓存对其进行缓存。例如,用户的浏览器能够缓存包含用户私人信息的 HTML 网页,但 CDN 却不能缓存。

  3. “max-age” 指令指定从请求的时间开始,容许获取的响应被重用的最长时间(单位:秒)。例如,“max-age=60”表示可在接下来的 60 秒缓存和重用响应。

定义最佳 Cache-Control 策略

这里写图片描述

按照以上决策树为您的应用使用的特定资源或一组资源肯定最佳缓存策略。在理想的状况下,您的目标应该是在客户端上缓存尽量多的响应,缓存尽量长的时间,而且为每一个响应提供验证令牌,以实现高效的从新验证。

Cache-Control 指令和说明
max-age=86400 浏览器以及任何中间缓存都可将响应(若是是“public”响应)缓存长达 1 天(60 秒 x 60 分钟 x 24 小时)。
private, max-age=600 客户端的浏览器只能将响应缓存最长 10 分钟(60 秒 x 10 分钟)。
no-store 不容许缓存响应,每次请求都必须完整获取。

根据 HTTP Archive,在排名最高的 300,000 个网站(按照 Alexa 排名)中,全部下载的响应中几乎有半数可由浏览器缓存,这能够大量减小重复的网页浏览和访问。固然,这并不意味着您的特定应用有 50% 的资源能够缓存。一些网站的资源 90% 以上均可以缓存,而其余网站可能有许多私密或时效要求高的数据根本没法缓存。

请审核您的网页,肯定哪些资源能够缓存,并确保它们返回正确的 Cache-Control 和 ETag 标头。

废弃和更新缓存的响应

  • 在资源“过时”以前,将一直使用本地缓存的响应。
  • 您能够经过在网址中嵌入文件内容指纹,强制客户端更新到新版本的响应。
  • 为得到最佳性能,每一个应用都须要定义本身的缓存层次结构。

客户端缓存和快速更新?您能够在资源内容发生变化时更改它的网址,强制用户下载新响应。一般状况下,能够经过在文件名中嵌入文件的指纹或版本号来实现 - 例如 style.x234dff.css。

这里写图片描述

缓存检查清单

不存在什么最佳缓存策略。您须要根据通讯模式、提供的数据类型以及应用特定的数据更新要求,为每一个资源定义和配置合适的设置,以及总体的“缓存层次结构”。

在制定缓存策略时,您须要牢记下面这些技巧和方法:

  1. 使用一致的网址 若是您在不一样的网址上提供相同的内容,将会屡次获取和存储这些内容。提示:请注意,网址区分大小写。

  2. 确保服务器提供验证令牌 (ETag) 有了验证令牌,当服务器上的资源未发生变化时,就不须要传送相同的字节。

  3. 肯定中间缓存能够缓存哪些资源 对全部用户的响应彻底相同的资源很是适合由 CDN 以及其余中间缓存进行缓存。

  4. 为每一个资源肯定最佳缓存周期 不一样的资源可能有不一样的更新要求。为每一个资源审核并肯定合适的 max-age。

  5. 肯定最适合您的网站的缓存层次结构 您能够经过为 HTML 文档组合使用包含内容指纹的资源网址和短期或 no-cache 周期,来控制客户端获取更新的速度。

  6. 最大限度减小搅动 某些资源的更新比其余资源频繁。若是资源的特定部分(例如 JavaScript 函数或 CSS 样式集)会常常更新,能够考虑将其代码做为单独的文件提供。这样一来,每次获取更新时,其他内容(例如变化不是很频繁的内容库代码)能够从缓存获取,从而最大限度减小下载的内容大小。

打开页面方式 IE6(httpwatch) FF3.5(httpfox)
1. 第一次打开页面 200 200
2. 重启浏览器打开页面 cache,即时发生资源修改也不会从新请求 cache,即时发生资源修改也不会从新请求
3. F5刷新 304,发生修改的资源状态为200 304,发生修改的资源状态为200
4. Ctrl+F5刷新 200,强制全新请求 200
5. 后退 cache,简单直接地从缓存加载 cache,简单直接地从缓存加载
6. 在已访问页面地址栏回车 cache cache
相关文章
相关标签/搜索