藏井阁

" Scientists ask why, engineers ask why not? "

第六章:把脚本放在底部 —《高性能网站建设指南》读书笔记

一般浏览器对同一域下的资源只能保持两个并发下载。无法修改用户的浏览器设置来增加并行下载数,但可以将资源存放到多个域下,来保持更多的并行连接,缩短页面加载速度。简单的实现就是对域名做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属性后,导致页面内容一闪就没了的问题。

类别: Web开发

Tags:

damon pang

大魔

Damo

i#impng.com

专注Web开发,爱电影,爱One Piece.