YAOHAIXIAO.COM

HTML(5),CSS(3),JavaScript,DOM,Ajax,JSON,Front-end technologies & Yaohaixiao

热门标签:JavaScript Performance 前端开发 前端性能优化 原创

Rss

Home » Frontend » Performance » 前端性能优化:Configure entity tags (ETags)

前端性能优化:Configure entity tags (ETags)

今天要介绍的YSlow的前端性能优化规则是 Configure entity tags (ETags)(配置(移除)实体标签)。

ETag 是什么?

实体标签(Entity Tag,ETag)是Web服务器和浏览器用于确认缓存组件的有效性的一种机制。ETag 在 HTTP 1.1 中开始引入。

ETag 和 Expires 的关系

ETag 既然是 Web服务器和浏览器用于确认缓存组件的有效性的一种机制,那么我们就不得不说一下ETag 和 Expires 的关系了。

前面《前端性能优化:Add Expires headers》中介绍过 Expires 头。我们可以通过在服务器端设置Expires 头,以便浏览器再次访问同一个页面组件时可以读取本地缓存中的文件,而减少HTTP请求。

条件GET请求

(说明:本节内容节选至《High Performance Web Sites》)

如果缓存的组件过期了(或者用户明确地重新加载了页面),浏览器在重用它之前必须首先检查它是否仍然有效(是否过期)。这称作一个条件GET请求。不过不幸的是浏览器必须产生这个HTTP请求,执行有效性检查,但这仍比简单地下载所有已过期的组件效率高。如果浏览器缓存中的组件是有效的(即它能够和原始服务器上的组件相匹配),原始服务器不会返回整个组件,而是返回一个“304 Not Modified”状态码。

服务器在检测缓存的组件是否和原始服务器上的组件匹配时有两种方式:

  • 比较最新修改日期
  • 比较实体标签

服务器会通过 Last-Modified 相应头来返回组件的最新修改日期,而浏览器会使用 If-Modified-Since 头将最新修改日期传回到服务器经行比较。如果比配,就会返回 304状态码,而不是重新下载组件。如下图:

ETag

而今天介绍的ETag 提供了另外一种方式,用于检测缓存中的组件是否于服务器上的是否匹配。ETag 是唯一标识了一个组件一个特定版本的字符串。例如:“50b1c1d4f775c61:df3”。ETag提供了更为灵活验证机制。浏览器会在请求头中以 If-None-Mache 头将ETag值传到服务器中进行比较。让然,如果比配就返回 304 状态码,而不用再次下载整个组件。

ETag 带来的性能问题

前面介绍过,ETag 是唯一标识了一个组件一个特定版本的字符串。而这个字符窜的生成对于不同的Web服务器有不同的格式:Apache 1.3 和 2.x 格式是 inode-size-timestamp、IIS 5.0 和 6.0 格式是 Filetimestamp:ChangeNumber、Nginx 1.3.3(开始原生支持)另外一种格式:

# Apache
Etag	"66214d231635cf1:d4b4a"
# IIS
Etag	"d3acc6a9ac4ce1:0"
# Nginx
Etag	"530ffeb9-a77c"

现在问题就出现了,不同的服务器对同一个组件会生成不同的ETag。如果你的网站只布置在一台服务器上,ETag只有一个格式,不会有问题。但是,如果大型的站点,使用了负载均衡的处理,在很多台不同的服务器上就会有很多不同版本的ETag值了。服务器越多,ETag匹配的概率就越小。例如网站发布到了10台服务器上,ETag值匹配的几率就只有10%,这就意味着另外90%的情况,浏览器不会读取缓存,而是重新请求组件。而这个则是我们不希望的多余的HTP请求。请求越多,加载就越慢。

前面说了,浏览器会同时发出 If-Modified-Since 头和 If-None-Mache 头去比较缓存的组件是否与服务器上的匹配。而研究的结果是 If-None-Mache 比 If-Modified-Since 有更高优先级。 也就是说,如果ETag不匹配,即使 Last-Modified 匹配浏览器仍旧会重新下载组件。《High Performance Web Sites》 中是这样介绍的:

依据HTTP 1.1规范(http://www.w3.org/protocols/rfc2616/rfc2616-sec13.html#sec13.3.4),如果请求中同时出现这两个头,则原始服务器“禁止 (MUST NOT) 返回 304 (Not Modified),除非请求中的条件头字段全部一致”。实际上如果根本没有 If-None-Mache 头反而会更好一些。

Configure entity tags (ETags)

我这里就谈该不该使用ETag,为了前端性能最好是移除ETag头。我这里就直接介绍不同服务器上如何配置,移除ETag:

################# 
# Apache
#################
<ifModule mod_expires.c>
    ExpiresActive On

    # special MIME type for icons - see http://www.iana.org/assignments/media-types/image/vnd.microsoft.icon
    AddType image/vnd.microsoft.icon .ico
	
    # now we have icon MIME type, we can use it
    # my favicon doesn't change much
    ExpiresByType image/vnd.microsoft.icon "access plus 1 years"

    ExpiresByType image/gif "access plus 1 months"
    ExpiresByType image/jpg "access plus 1 months"
    ExpiresByType image/jpeg "access plus 1 months"
    ExpiresByType image/png "access plus 1 months"
    ExpiresByType image/vnd.microsoft.icon "access plus 1 months"
    ExpiresByType image/x-icon "access plus 1 years"
    ExpiresByType image/ico "access plus 1 years"
    ExpiresByType application/javascript "now plus 1 months”
    ExpiresByType application/x-javascript "now plus 1 months”
    ExpiresByType text/javascript "now plus 1 months”
    ExpiresByType text/css "now plus 1 months”
    ExpiresDefault "access plus 1 days"

    # Header unset ETag
    FileETag None
</ifModule>

################# 
# Nginx 1.3.3 以上 - see http://nginx.org/en/docs/http/ngx_http_core_module.html#etag
#################
syntax: 	etag on | off;
default: 	etag on;
context: 	http, server, location
-------------------------------------------
This directive appeared in version 1.3.3. 

http{
    # 移除 ETag
    etag off;
}

server{
    # 移除 ETag
    etag off;
}

location{
    # 移除 ETag
    etag off;
}

################# 
# IIS 5.0 - 6.0 - see http://support.microsoft.com/?id=922733
#################
若要从 Web 服务器检索 ETag 值并设置的所有其他 Web 服务器上的同一个 ETag 值,请执行以下步骤:

  1. 单击开始,单击运行,键入cmd,然后单击确定
  2. 在命令提示符处,键入以下命令,然后按 ENTER:
    光盘output
  3. 在一个 Web 服务器上的命令提示符下键入以下命令,然后按 ENTER:
    Mdutil.exe 获得 w3svc-属性 2039年
    此命令将从 Web 服务器检索的 ETag 值。
  4. 在所有其他 Web 服务器上的命令提示符下键入以下命令,然后按 ENTER:
    Mdutil.exe 设置 w3svc-属性 2039年 –value"entitytagvalue"
    注意:在此命令中, entitytagvalue是您在步骤 3 中检索到的 ETag 值的占位符。

    该命令设置的所有其他 Web 服务器上的同一个 ETag 值。
  5. 所有 Web 服务器上运行 IIS 5.0 Web 服务器场中,重新启动 IIS 5.0。
注意:Mdutil.exe 工具不受支持的工具,是未记录。如果您需要帮助使用 Mdutil.exe 工具,请在命令提示符下键入mdutil.exe 。 ################# # IIS 7.0-8.0 - see Remove ETags HTTP response header on IIS 7 / 7.5 / 8.0 ################# <httpProtocol> <customHeaders> <remove name="ETag"/> <add name="ETag" value="""" /> </customHeaders> </httpProtocol> <outboundRules> <rule name="Remove ETag"> <match serverVariable="RESPONSE_ETag" pattern=".+" /> <action type="Rewrite" value="" /> </rule> </outboundRules>

IIS 的处理最麻烦,《High Performance Web Sites》 和 YSlow 中都没有介绍IIS的配置处理,估计是国外的Web服务器使用Window系统的不多,大家也只有仔细看看 Microsoft Support 的文档了。当然,我这里要再次提醒是的,如果你的网站就只是在布置在一台服务器上,就没有必要移除ETag了,只有在服务器布置在服务器集群时移除ETag才是有必要的。

声明:本文采用BY-NC-SA协议进行授权。转载请注明转自:前端性能优化:Configure entity tags (ETags)

« »

发表评论

电子邮件地址不会被公开。 必填项已用*标注

您可以使用这些HTML标签和属性: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

(Spamcheck Enabled)