网站性能优化-将Script放到HTML文件中尽量靠近尾部原理

在Yahoo的网站性能优化准则里,其中有一条是将Script放在页面底部,

 

Put Scripts at the Bottom

tag: javascript

The problem caused by scripts is that they block parallel downloads. The HTTP/1.1 specification suggests that browsers download no more than two components in parallel per hostname. If you serve your images from multiple hostnames, you can get more than two downloads to occur in parallel. While a script is downloading, however, the browser won't start any other downloads, even on different hostnames.

In some situations it's not easy to move scripts to the bottom. If, for example, the script uses document.write to insert part of the page's content, it can't be moved lower in the page. There might also be scoping issues. In many cases, there are ways to workaround these situations.

An alternative suggestion that often comes up is to use deferred scripts. The DEFER attribute indicates that the script does not contain document.write, and is a clue to browsers that they can continue rendering. Unfortunately, Firefox doesn't support the DEFER attribute. In Internet Explorer, the script may be deferred, but not as much as desired. If a script can be deferred, it can also be moved to the bottom of the page. That will make your web pages load faster.

top | discuss this rule

 

原文参见:http://developer.yahoo.com/performance/rules.html

 

对于这个原则,源于浏览器对Script下载的非并行处理。下面我对这条原则进行测试说明。

 

首先,浏览器对于script的下载是避免并行进行的。HTTP/1.1协议中规定浏览器和同一host之间只建立最多两个连接,也就是说允许的最大并行度为2(当然,对IE和Firefox来说,你都可以通过修改浏览器的设置来扩大这个并行度,但是,并发数越高,占用CPU和带宽就越大)。但对于Script的下载来说,浏览器在开始下载Script之后,是不会并行的下载其他element的。不会并行下载script这一点是一个事实,但浏览器为什么要采用这种策略,以及浏览器我们提到的“将Script放到HTML文件中尽量靠近尾部”到底能起到多大的作用,需要注意哪些事项,我希望在这篇文章中进一步的进行讨论。

为了讨论方便,我准备了一个简单的HTML文件:

 

这个HTML文件include了两个javascript文件,含有两张图片。两个javascript文件内容分别如下:
jsdownload_j1.js:

 

 

download_j2.js:

 

 

  从代码中看出,这个HTML文件很简单,带有两张图片和一个button,当button被click的时候,调用jsdownload_j2.js的OnB1Click()函数,而OnB1Click()函数是简单的调用jsdownload_j1.js文件中的OnJ1B1Click()函数。

      我们来看看用IBM Page Detailer工具获得的IE浏览器访问该页面时的页面元素下载图:

 

 

从图中可以看到,javascript的下载block了其他元素的下载,因此第一个可视元素(图片)的下载完成是在1.33秒的时刻,也就是说,用户等待1.33秒才能看到页面上的第一幅图片。

而如果我们把HTML中的javascript的位置放到稍后的位置,例如,改成这样:

 

则得到的element下载图如下:

        虽然总的下载时间比上一次稍长,但在0.72秒的时候,第一幅图片就已经下载完成,此时用户会看到页面的主要部分,因此对用户来说,页面变“快”了。

        这是一个典型的利用浏览器下载Script时候的非并行特性优化页面性能的方法。接下来,我们讨论下为什么浏览器在下载Script的时候会采用非并行的方式。其实原因也不复杂:

        在我们的HTML文件中,有两个Script,一个是jsdownload_j1.js,另一个是jsdownload_j2.js文件,如果允许浏览器并行下载这两个script,则可能发生jsdownload_j2.js文件先于jsdownload_j1.js文件下载完成的情况。这时如果页面上后续的一个javascript调用使用了jsdownload_j2.js文件中的函数,则此调用会立即发生(因为浏览器判断到jsdownload_j2.js文件已经下载完成了),而如果此时jsdownload_j2.js文件中的该函数需要依赖于jsdownload_j1.js中的另一个函数,由于此时jsdownload_j1.js文件还未下载完成,则此调用会产生一个javascript error。为了避免这样的情况,浏览器采用了严格按照HTML文件中定义的顺序下载Script,并严格按照非并行方式下载的策略。

        最后一个需要讨论的问题,就是这种提升页面性能的方式有哪些需要注意的内容了。实际上,如同上面黑体字的讨论,如果不分青红皂白把Script文件全部放在HTML的最后部分,也是会出问题的。例如,在我们的例子中,Button的Click事件需要调用js文件中的某个函数,如果Script都被放到HTML文件的最后的话,button这个element会在script下载完成之前被render出来,如果此时用户点击了这个button,就一定会出现一个Script error。关于这个问题,有两个解决方法:
1,将Script放在合适的,尽量靠近尾部的地方,由开发人员保证不会出现这样的问题;
2,为所有的js文件中需要被调用的函数,在HTML中实现一个空函数(放在靠前的位置),这样当页面需要的js文件没有download完成时,用户点击按钮等操作之后出发一个空函数,避免了Script Error(当然,可能会confuse用户);而等js文件download完成后,这些function会被override,用户的操作能够得到正确的解决。

 

 

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值