YSLOW性能测试前端调优23大规则(6)将脚本放在底部

YSLOW性能测试前端调优23大规则(6)将脚本放在底部
本小节主要讨论在处理HTTP请求时脚本应该放在什么位置比较合理。因为当脚本正在下载时,浏览器交示会启动任何其它的下载,也就是说当下载脚本时浏览器并行下载的功能将被禁用的,即使是在不同的主机名上。

当然阻塞脚本并行下载通常有以下两种原因:

第一:脚本可能使用document.write来修改页面内容,因此浏览器会等待,以确保页面能够正确的布局。

第二:为了保证脚本能够按照正确的顺序执行,如果并行下载多个其它的脚本,就无法保证响应是按照指定的顺序到达浏览器。例如,如果后面的脚本比前面的脚本更小时,那么后面的脚本可能先下载好并执行,这样如果这两个脚本存在依赖关系时,脚本运行就可以会出现JavaScript的相关错误。

现在的浏览器是不能一次性将所有的请求都下载下来的,但浏览器一般都支持并行下载。对响应时间影响最大的是页面中组件的数量,如果缓存为空,那么每个组件都会产生一个HTTP请求,有时即便缓存是完整的也是如此。

HTTP 1.1规范指明:浏览器应允许每个主机名(hostname)可以支持至少两个并发连接(尽管新的浏览器支持更多的并发数)。如果一个HTML文档包含的资源引用(如CSS、Javascript、图片等)比主机允许的最大并发数多,浏览器则发出允许的最大并发数的请求,并将剩余的请求加入队列中。一旦有请求完成,浏览器会立即发出队列中的下一批允许的最大并发数的请求,它会一直重复这个过程直到下载完所有的资源。也就是说,如果一个页面从一个主机引用了超过N数量(N为每个主机允许的最大连接数)的HTTP请求,那么浏览器就必须按顺序依次下载它们。每N个资源耗费1个往返时间(RTT,Round-Trip Time),所以总的请求往返时间为M/N(M为从一个主机上获取的资源数);例如:如果一个浏览器允许每个主机名可以有6个并发连接,并且一个页面可以引用同域的90个资源,那么每6个资源会占用1个往返时间,总的下载时间为15个往返时间。

在Firefox浏览器中,可以在about:config页面中设置最大并发连接数,在Firefox浏览器的地址栏中输入“about:config”,会显示出所有相关参数。

network.http.max-connections:表示最大连接数

network.http.keep-alive.timeout:表示保持长连接的超时时间

network.http.max-persistent-connections-per-server:表示支持的最大并发连接数,默认值为6。

在Chrome浏览器中,可以在chrome://flags/页面中设置并发连接的情况,在Chrome浏览器的地址栏中输入“chrome://flags/”,会显出所有相关参数。

参数Parallel downloading用于设置并发下载的情况。

主流浏览器所支持的并发连接数见表。
YSLOW性能测试前端调优23大规则(6)将脚本放在底部
HTTP1.1规范中一般是建议浏览器从每个主机名并行下载两个组件,但实际上现在市场上主流的浏览器都支持更多的并行下载组件,如果支持并行下载组件的话,我们会看到HTTP请求是呈阶梯状态的,以Chrome为例,捉到的HTTP请求的情况如图所示。
YSLOW性能测试前端调优23大规则(6)将脚本放在底部
Chrome默认是支持6个请求同时并发,所以我们可以看到HTTP请求很明显的呈阶梯状态,每次同时下载6个组件,这样可以大大的提高响应时间。

并行下载组件的目的是提高下载组件的响应时间,但当我们在下载JS脚本组件时会将浏览器并发下载组件的功能禁用,看下面一个实例:

并行加载测试

并行加载测试

YSLOW性能测试前端调优23大规则(6)将脚本放在底部 //加载图片

YSLOW性能测试前端调优23大规则(6)将脚本放在底部 //加载图片

//加载JS文件,睡10秒

YSLOW性能测试前端调优23大规则(6)将脚本放在底部 //加载图片

捉到的HTTP请求结果如图所示。
YSLOW性能测试前端调优23大规则(6)将脚本放在底部
从图中可以看到图片tenpay.gif和tenpayc2c.jpg加载完成后,是加载test.js文件和wap_logo.png图片。正常理解这四个组件应该是同时下载的,但是当我们有JS文件在中间时后面的wap_logo.png图片并没有并行下载,而应该是等test.js文件加载完成后才开始下载,这样就会阻止后面的组件下载,直到test.js下载完成后才能开始下载。

为了解决这个阻塞的问题,最好的办法是将JS脚本放在页面的底部,这样不会阻止页面内容的呈现,并且这样页面中的可视组件可以迟早下载。

最糟糕的情况是将JS脚本放在页面顶部,这样脚本会阻塞对其后面内容的呈现,也会阻塞对其后面组件的下载。所以一般情况下我们建议将JS脚本文件放在页面底部。