第六章:把脚本放在底部 —《高性能网站建设指南》读书笔记
一般浏览器对同一域下的资源只能保持两个并发下载。无法修改用户的浏览器设置来增加并行下载数,但可以将资源存放到多个域下,来保持更多的并行连接,缩短页面加载速度。简单的实现就是对域名做CNAME,Yahoo!的研究表明,使用两个域来加载资源效果是比较好的。
脚本会阻塞并行下载。在下载脚本时,并行下载是被禁用的,因为脚本加载完后,可能会对页面进行大面积的布局变动,浏览器会等待脚本加载完毕,减少布局的频繁变动带来的开销。同时,阻塞并行下载可以保证脚本的按顺序执行,避免有依赖关系的脚本执行次序的混乱引起的出错。
若将脚本放到页面的最顶部,若脚本加载速度较慢,则页面会呈现很明显的白屏。如下面的一个简单例子:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title>js加载阻塞其他资源的加载 <script src="http://localhost/load_long_time.php" type="text/javascript"> </head> <body> <img src="http://www.impng.com/images/impng.jpg" /> </body> </html>
然后在load_long_time.php文件内,加入简单的一个延迟语句即可:
sleep(10); // 等待十秒
可以看到明显的白屏,需要等脚本加载完毕后,才会加载图片。
除了将脚本放到页面底部,还可以通过script标签的defer属性来避免,但需要酌情使用。属性defer指定脚本不用立即执行,而是等到页面全部加载完毕后执行。浏览器根据此属性会继续下面的加载和呈现,而不会阻塞加载。书中提到,defer在firefox中不支持,还是会阻塞并行下载和呈现,但是根据我的测试,在最新的Firefox版本(3.6.3)中,并不会阻塞下载和呈现。可以修改上面的例子来测试:
<script src="http://localhost/load_long_time.php" type="text/javascript" defer="defer">
摘自yzxchoice,使用defer属性时,需要注意:
- 1. 不要在defer型的脚本程序段中调用document.write命令,因为document.write将产生直接输出效果。
- 2. 不要在defer型脚本程序段中包括任何立即执行脚本要使用的全局变量或者函数。
文中举出在google ads的script加上defer属性后,导致页面内容一闪就没了的问题。