YSLOW性能测试前端调优23大规则(11)避免重定向

YSLOW性能测试前端调优23大规则(11)避免重定向
URL 重定向(Redirects),也称为 URL 转发,是一种当实际资源,如单个页面、表单或者整个 Web 应用被迁移到新的 URL 下的时候,保持(原有)链接可用的技术。HTTP 协议提供了一种特殊形式的响应—— HTTP 重定向(HTTP redirects)来执行此类操作,该操作可以应用于多种多样的目标:网站维护期间的临时跳转,网站架构改变后为了保持外部链接继续可用的永久重定向,上传文件时的表示进度的页面等等。

在 HTTP 协议中,重定向操作由服务器通过发送特殊的响应(即 redirects)而触发。HTTP 协议的重定向响应的状态码为 3xx 。浏览器在接收到重定向响应的时候,会采用该响应提供的新的 URL ,并立即进行加载;大多数情况下,除了会有一小部分性能损失之外,重定向操作对于用户来说是不可见的。重定向的原理如图所示。
YSLOW性能测试前端调优23大规则(11)避免重定向
关于重定向通常有以下几种类型:

  1. 301

如果返回的状态码为301,表示被请求的资源已永久移动(Moved Permanently),永久移动到新位置,任何对此资源的引用都应该使用本响应返回的若干个URI之一。如果可能,拥有链接编辑功能的客户端应当自动把请求的地址修改为从服务器反馈回来的地址。正常这个响应是可缓存的,除非额外指定。新的永久性的URI应当在响应的Location域中返回,正常实体中应当包含指向新的URL的超链接及简短说明,除非是HEAD类的请求。

  1. 302

如果返回状态码302,表示要求客户端临时重宝向(Moved Temporarily)。由于是临时重定向,客户端应当继续向原有地址发送以后的请求,并且只有在Cache-Control或Expires中指定的情况下,响应才可以缓存。注意:虽然RFC 1945和RFC 2068规范不允许客户端在重定向时改变请求的方法,但是很多现存的浏览器将302响应视作为303响应,并且使用GET方式访问在Location中规定的URI,而无视原先请求的方法。因此状态码303和307被添加了进来,用以明确服务器期待客户端进行何种反应。

  1. 303

如果返回状态码303,表示对应当前请求的响应可以在另一个URI上被找到,客户端假定服务器已经收到数据,并且应该使用单独的GET消息发出重定向。这个方法的存在主要是为了允许由脚本**的POST请求输出重定向到一个新的资源。这个新的URI不是原始资源的替代引用。同时,303响应禁止被缓存。当然,第二个请求(重定向)可能被缓存。新的URI应当在响应的Location域中返回。除非这是一个HEAD请求,否则响应的实体中应当包含指向新的URI的超链接及简短说明。注意:许多HTTP/1.1版以前的浏览器不能正确理解303状态。如果需要考虑与这些浏览器之间的互动,302状态码应该可以胜任,因为大多数的浏览器处理302响应时的方式恰恰就是上述规范要求客户端处理303响应时应当做的。

  1. 307

307状态码也是表示临时从不同的URI响应请求,请求应该与另一个URI重复,这个与302类似,但307不允许更好请求方法,但后续的请求应仍使用原始的URI。 例如,应该使用另一个POST请求来重复POST请求。

  1. 304

如果返回状态码304,表示客户端在请求一个文件的时候,发现自己缓存的文件有Last Modified,此时请求中会包含If Modified Since,这个时间就是缓存文件的Last Modified。因此,如果请求中包含If Modified Since,就说明已经有缓存在客户端。服务端只要判断这个时间和当前请求的文件的修改时间就可以确定是返回304还是200。

对于静态文件(如:CSS、图片等),服务器会自动完成Last Modified和If Modified Since的比较完成缓存或者更新。但是对于动态页面,就是动态产生的页面,往往没有包含Last Modified信息,浏览器、网关等都不会做缓存,也就是在每次请求的时候都完成一个200的请求。因此,对于动态页面做缓存加速,首先要在Response的HTTP Header中增加Last Modified定义,其次根据Request中的If Modified Since和被请求内容的更新时间来返回200或者304。虽然在返回304的时候已经做了一次数据库查询,但是可以避免接下来更多的数据库查询,并且没有返回页面内容而只是一个HTTP Header,从而大大的降低带宽的消耗,对于用户的感觉也是提高。

  1. 300

如果返回状态码304,表示被请求的资源有一系列可供选择的回馈信息,每个都有自己特定的地址和浏览器驱动的商议信息。用户或浏览器能够自行选择一个首选的地址进行重定向。除非这是一个HEAD请求,否则该响应应当包括一个资源特性及地址的列表的实体,以便用户或浏览器从中选择最合适的重定向地址。这个实体的格式由Content-Type定义的格式所决定。浏览器可能根据响应的格式以及浏览器自身能力,自动作出最合适的选择。当然,RFC 2616规范并没有规定这样的自动选择该如何进行。如果服务器本身已经有了首选的回馈选择,那么在Location中应当指明这个回馈的URI;浏览器可能会将这个Location值作为自动重定向的地址。此外,除非额外指定,否则这个响应也是可缓存的。

不同类型的重定向映射可以划分为三个类别:永久重定向、临时重定向和特殊重定向。上面的重定向类型中301属于永久重定向类型,302、303和307属于临时重定向类型,300和304是特殊重定向类型。

重定向是如何损伤性能的呢?如下图13-10所示是一个重定的实例,第一个HTTP请求就是重定向,在重定向页面加载完成后才会下载其它的组件,直到HTML文档整个下载完成后,用户才会在界面看到显示的内容。

如果要检测页面是否有重定向,可以使用重定向映射工具检查页面上的重定向(它会检测并显示301和302重定向)。检查所有网页重定向并查看网站,考虑如何更改网页,衡量影响页面性能变慢的可能性。

关于如何避免重定向或者将重定向的影响降低到最小化通常有以下几种方法:

a) 删除并非绝对必要的重定向

删除并非绝对必要的重定向,再通过其它的方式进行重定向。永远不要链接你已经知道的重定向的页面,永远不要访问经过多次重定向才能访问的资源。

b) 结尾的斜线

通常,带有结尾带有斜线的URL表示目录,而没有带斜线的URL表示文件。

http://http://example.com/foo/表示目录。

http://http://example.com/foo表示文件。

即使有区别,但很多网站并不区分这两者的不同,然后搜索引擎确实会将这两种情况视为不同的实体。用户发现这两种URL的方式可能导致内容混乱。对于用户定向到相同内容的URL,必须进行某种类型的重定向,要确定从哪 个URL重定向到哪个URL,并检查哪个URL返回的HTTP响应代码为200,哪个URL 返回的HTTP响应码为30X。

通常,您不希望篡改此类重定向,但在网页上配置链接时,您将需要知道哪个站点是主站点,哪个站点导致重定向。通过直接链接到站点,您可以减少在网页上使用重定向。

c) 重定向的不仅仅是HTML

在加载页面时其实不仅仅是HTML文档,还有很多其它的组件。那么如果HTML中没有重定向就表示这整个页面都没有重定向吗?那不一定HTML中没有重定向,但CSS文件、图像、外部JavaScript文件也可能有重定向,所以需要确保页面在调用时加载了哪些资源,可以使用页面的相关工具来测试。确保不创建重定向的方式调用所有资源。

d) 检查旧的重定向

检查旧的重定向的使用情况,我们可以通过检查.htaccess文件或其他服务器配置文件来检查旧的重定向,这些旧的重定向可能是以前某个页面或某个部件添加的,需要检查这些旧的重定向还在使用,有的基础可能不存在的,但这个并不是很容易去发现。

e) 删除不需要的重定向

删除不需要的重定向,通常使用以下步骤:

第一步:查找重定向。

第二步:了解重定向存在的原因。

第三步:确定它是如何影响或受其他重定向影响的。

第四步:如果不需要,则删除这个重定向。

第五步:如果它影响或受其它重定向影响,那么需要对这个重定向进行更新。

第六步:如果站点是安全的,那么可以考虑使用HSTS删除SSL重定向。

f) 清理重定向链

除了需要删除重定向之外,还需要清理重定向链。将所有站点重定向从非www版本到www版本,然后再重定向到https版本。例如键入“test.com”的用户重定向到“www.test.com”然后再重定向到“https:// www.test.com”,这种情况经常有发生。解决的方案是确保旧的全站点重定向不会从非www到www,而是从非www到https://www。