配置ETags

前言

网站设计的优化是一个很大的话题,有一些通用的原则,也有针对不一样开发平台的一些建议。这方面的研究一直没有中止过,我在不一样的场合也分享过这样的话题。php

做为通用的原则,雅虎的工程师团队曾经给出过35个最佳实践。这个列表请参考  Best Practices for Speeding Up Your Web Site http://developer.yahoo.com/performance/rules.html,同时,他们还发布了一个相应的测试工具Yslow http://developer.yahoo.com/yslow/html

我强烈推荐全部的网站开发人员都应该学习这些最佳实践,并结合本身的实际项目状况进行应用。 接下来的一段时间,我将结合ASP.NET这个开发平台,针对这些原则,经过一个系列文章的形式,作些讲解和演绎,以帮助你们更好地理解这些原则,而且更好地使用他们。web

准备工做

为了跟随我进行后续的学习,你须要准备以下的开发环境和工具算法

  1. Google Chrome 或者firefox ,而且安装 Yslow这个扩展组件.请注意,这个组件是雅虎提供的,但目前没有针对IE的版本。
    1. https://chrome.google.com/webstore/detail/yslow/ninejjcohidippngpapiilnmkgllmakh
    2. https://addons.mozilla.org/en-US/firefox/addon/yslow/
    3. 你应该对这些浏览器的开发人员工具备所了解,你能够经过按下F12键调出这个工具。
  2. Visaul Studio 2010 SP1 或更高版本,推荐使用Visual Studio 2012
    1. http://www.microsoft.com/visualstudio/eng/downloads
  3. 你须要对ASP.NET的开发基本流程和核心技术有至关的了解,本系列文章很难对基础知识作普及。

本文要讨论的话题

这一篇我和你们讨论的是第十三条原则:Configure ETags (配置ETags)。chrome

ETag,全称为:Entity Tag,意思是实体标签,从名字上看,是对于某种实体的一个标识。它属于HTTP协议的一部分,也就是全部的Web服务器都应该(也确实能)支持这个特性。它的做用是用一个特殊的字符串来标识某个资源的“版本”,客户端(浏览器)来请求的时候,能够比较,若是ETag一致,则表示该资源并无修改过,客户端(浏览器)可使用本身缓存的版本。api

工做原理

咱们经过实例来了解ETag的工做原理,当用户第一次请求某个资源(一般为静态资源)的时候浏览器

image

正常状况下,他将获得一个状态码为200的响应,而且在响应头部中会包含一个ETag的信息(ETag    "6ab823201a4ece1:0")缓存

image

【备注】这个值是我本机的IIS 8.0提供,不一样的服务器可能会有所不一样。我后面会解释大体的含义。服务器

 

接下来,若是用户再次请求这个资源的话,浏览器会尝试在请求头部中包含这个信息,以便服务器能够比较,肯定是要再次发送资源的内容。工具

image

咱们注意这一行 If-None-Match    "6ab823201a4ece1:0"

而后,服务器会怎么样响应这个请求呢?

image

服务器其实是比较了ETag的值,它发现浏览器提供的值与该资源实际的值是同样的,因此它就返回了304的状态码,并且不须要在响应的正文里面包含任何实际内容。浏览器获得304这个状态码以后,就知道该资源并无被修改,因此直接使用本地缓存的版本。

 

ETag的配置

在IIS产品家族中,新的版本(例如IIS 7之后的版本)会自动配置一个ETag,这个ETag的值很相似于下面这样:

6ab823201a4ece1:0

它是由两个部分组成的

  1. 第一部分称为FileTimeStamp(时间戳),咱们很容易联想到这多是跟文档修改时间有关系,事实上确实是,但你没法将其直接还原为文档修改时间(微软并无公开这部分的算法)。我确实对此作过一些研究,但最终仍是没有办法解释这个值如何生成的,因此你们也只须要知道,这个是相似于一个时间戳的值就能够了。
  2. 第二部分为ChangeNumber(修改编号)。这个值在IIS 7.0以及后续的版本中,被统一设置为0。设置为一个统一值有利于解决一些问题(例如在服务器场模式下,该问题我后续也会讨论到)。事实上,保留这个ChangeNumber我以为主要是历史遗留问题,由于早期版本是有这个值,并且能够不同。既然若是这个值不同的话,会给咱们惹一些麻烦,那么其实最好的作法是干脆就不要这个字段了。但我想,为了保持格式上的一向性,微软最终保留了这个字段。

 

这个默认的ETag不须要任何的配置就会存在(反过来,你若是要删除它却是很不容易,这个问题后续也会提到),但咱们能够继续添加本身想要的特殊ETag。也就是说,对于一个资源,其实是能够有多个ETag的。咱们看看在IIS 中的设置。

image

image

你能够在这里设置任意的值。

咱们能够预见到,若是这样设置的话,那么在响应的头部中应该就会有多个ETag了。以下图所示

image

 

ETag与其余技术的比较

通过上面的介绍,你们应该知道ETag的功能,主要能提供对资源的版本标识,以免无谓的重复下载。这从必定意义上,确定是有利的,它能够提升性能。

若是这样的话,那么它和“优化网站设计(三):对资源添加缓存控制” 中提到过的一些技术比较起来,有什么本身的特色呢?

响应标头 优点 和特色 劣势 和可能的问题
Expires
  • HTTP 1.0就有,简单易用。
  • 服务器经过这个Header告诉浏览器,某资源直到某个时间才会过时,因此在没有过时以前,浏览器就直接使用本地的缓存了。
  • 由于这是时间是由服务器发送的(UTC),但若是服务器时间和客户端事件存在不一致,可能会有些问题。
  • 可能存在版本的问题,由于若是在到期以前修改过了,客户端是不会知道的。
  • Cache-Control中的max-age能够实现相似的效果,但更加好,由于max-age是一个以秒为单位的时间数,而不是具体的时间,因此不存在上面提到的第一个问题。

Cache-Control

  • 服务器经过一个Header(Last-Modified)告诉浏览器,某资源最后修改的时间
  • 浏览器在请求的时候,包含一个Header(If-Modified-Since),而后服务器能够进行比较,若是在该时间后没有修改过,则返回304
  • 它比Expires多不少选项设置
  • Last-Modified 也是一个时间,但该时间只能精确到秒,若是在同一个秒中有屡次修改(这个在如今的环境下应该确实是可能的),则可能会发生问题。
ETag
  • 能够更加精确地判断资源是否被修改,由于它不是一个时间值,而是对时间通过处理的一个长整型数值(固然具体算法咱们目前还不得而知)
  • 浏览器发起新请求时须要包含 If-None-Match
  • 若是部署在服务器场环境中,配置不当的话,可能每一个服务器会对相同的资源生成不同的ETag,这样就增长了重复下载的可能性。要理解这个问题的缘由,以及如何解决,请参考这里的文档:http://support.microsoft.com/kb/922703/en-us
  • 该问题在IIS 7以及之后的版本中应该不存在了

这几个技术其实不少时候是会结合起来用的,并且优先级也有所不一样。一般,ETag是优先于Cache-Control的,而Cache-Control又是优先于Expires的

clip_image006

 

 

什么时候以及如何删除ETag的功能?

因为以前谈到可能的一些问题,雅虎团队在当年写这个原则的时候,是建议在服务器场的环境下面禁用ETag的,在Apache中,能够经过修改配置文件来实现。而在IIS 中,若是你所使用的是7.0以及后续的版本,实际上应该能够不由用,由于如今不会存在他们所提到的那个问题了。但若是你真的想要了解一下如何禁用,那么请参考下面的操做

  1. 安装这个扩展:http://www.iis.net/downloads/microsoft/url-rewrite 
  2. 建立一个地址重写规则

image

image

image

这样配置了以后,就不会再有ETag,整个世界清静了。

相关文章
相关标签/搜索