翻译:High Performance Web Sites(2)-Chapter B | iJohn.org
18th
二月 2008

翻译:High Performance Web Sites(2)-Chapter B
爱因万江斯坦@2008年02月18日 23:36 Post in 性能 评论 »

《High Performance Web Sites》 :Chapter B

HTTP Overview

在开始介绍具体的优化法则之前,您务必要理解超文本传输协议:HyperText Transfer Protocol(HTTP)对性能的影响。HTTP是浏览器与服务器之间通过Internet通信的方式。HTTP的规范是由万维网联盟:W3C(World Wide Web Consortium)和互联网工程任务组:IETF(Internet Engineering Task Force)共同制定,而最终形成的RFC 2616规范。HTTP/1.1是目前流行通用的版本了,但还是有一些浏览器只支持HTTP/1.0。

HTTP就是描述请求request和响应response的c/s模型协议。一个浏览器发送HTTP请求(request)到一个指定的URL,这个URL所指定的服务器接到请求后返回一个HTTP响应(response)给浏览器,就这么简单。与很多互联网服务一样,这个协议用的是简单的明文格式。请求的种类有:GET,POST,HEAD,PUT,DELETE,OPTIONS和TRACE。下面我只重点介绍GET请求,这一最常用的。

一个GET请求把所请求的URL组装在头信息(headers)中,然后发送到这个指定的URL。服务器接收到请求后,经过响应处理,返回一个包含状态码,头信息(headers)和具体明文文本(一般是Html源码)所组装的数据包。如下图,就是请求yahoo_2.0.0-b2.js时的HTTP头信息(headers)的内容示例。

压缩
如果浏览器和服务器都支持,可以通过压缩来减少响应返回时的数据量。浏览器通过头信息中的Accept-Encoding元素来告诉服务器是否可以接受压缩数据,以及何种压缩方式。而服务器则通过头信息中的Content-Encoding元素来告诉浏览器,我目前支持哪种压缩方式。如下图

 

注意上图中返回的数据是已经被压缩的数据。Chapter 4会专门介绍HTTP压缩,以及在代理缓存下产生的一些问题,当然还会讨论一些其它的头信息(headers)。

有条件的GET请求  Conditional GET Request
如果浏览器已经缓存了一个组件,但是浏览器该怎么知道这个组件是否还有效呢,于是就产生了有条件的GET请求。如果缓存里的组件是有效的,浏览器就继续使用这个组件来加载页面,以减少响应的数据量从而加速了用户体验。

一般来说,判断缓存的组件是否有效是检查它的最后修时间。浏览器通过response响应数据中名为Last-Modified的头信息来获取这个时间值。再次有相同组件的GET请求时,浏览器会将名为If-Modified-Since头信息随GET请求一起发送到服务器,带着这一条件信息给远程的服务器,这就好像是浏览器对服务器呐喊:”我已经有一个版本的组件了,这里它的最后修改时间,这次我还可以继续使用它吗?”(只要网络不断,服务器总是会听见这呐喊声的)

 

如果这个组件在这个Last-Modified描述的时间之后没有被修改过,服务器就不会返回这个组件的具体数据了,而返回一个”304 Not Modified”状态码,这样可不就提高了响应速度了。在HTTP/1.1里,名为ETag和If-None-Match的头信息也可以起到类似的作用,这两个都会在Chapter 13中有讨论。

过期 Expires

有条件的GET请求和返回304状态码能让页面载入的更快,但它还是需要在客户端和服务器端进行一个往返的验证过程,HTTP请求仍然存在。而名为Expires的头信息会则会避免这种验证过程。

 

一旦浏览器发现响应返回的头信息中有Expires属性,它就会把这个属性所描述的日期与组件保存到浏览器缓存中,只要再次访问这个组件时的日期没有超过Expires属性里描述的日期,就会一直被浏览器使用而不会再次发送HTTP请求。Chapter 3会有关于Expires和Cache-Control头信息的更多介绍。

Keep-Alive

HTTP是建立在TCP协议的上层的实现,在早期的HTTP实现中,每个HTTP请求都会打开一个新的socket连接。实际上效率很低,因为大多数的HTTP请求都是针对同一个服务器发出的(想像一下我们浏览一个页面的情形,是不是该页面的组件大多数都是在这个页面所host的服务器上)。于是,长连接(persistent connections)的概念被引入了HTTP,以解决这种同一个服务器不停地打开关闭socket连接的情况。它能够让浏览器的多个请求只通过一个连接完成。浏览器和服务器就是通过相互传递Keep-Alive头信息来判断是否支持这一特性。

 

浏览器或服务器可以通过发送一个close头信息来关闭连接。从规范来说,keep-alive并不包含在HTTP/1.1中,但是绝大多数浏览器和服务器还是支持这一特性的。

Pipelining, 定义在HTTP/1.1中,它允许在一个socket连接中发送多个请求而不用等待响应返回。Pipelining比长连接(persistent connections)有着更好的性能。但是很不幸,IE不支持(IE7已经支持了),FireFox 2以后的版本虽然支持,但默认是关闭的。所以在Pipelining还没能普及以前,我们就还只能用Keep-Alive的方式来优化浏览器与服务器之间通过socket的通信。这个特性对于HTTPS很重要,因为HTTPS的连接都是长时间的连接.

更多

这个章节只是大致的介绍了HTTP,并把重点放在介绍影响性能的方面。如果要了解更多,您可以参考HTTP规范(http://www.w3.org/Protocols/rfc2616/rfc2616.html和由David Gourley 与 Brian Totty编写的《HTTP: The Definitive Guide》(O’Reilly; http://www.oreilly.com/catalog/httptdg)。上面所例举的资料将会您理解我们后台的章节有很大的帮助。

 

Leave a Reply