高性能网站建设进阶指南(二)
第四章 无阻塞加载脚本
阻塞:大部分浏览器在下载或执行<script>标签内容时不会下载其他内容。浏览器是按顺序执行的,但不一定要按顺序下载脚本。
对于外部脚本,如果浏览器缓存中有,就从缓存中读取,否则发送HTTP请求获取。
解决阻塞:
(1)把所有的<script>中的代码内嵌在HTML页面中,这种方法不推荐使用。
(2)XHR Eval、XHR注入、Script in Iframe(iframe是页面中开销最高的DoM元素),这两个的缺点:通过XHR获取的脚本必须部署在和主页面相同的域下
(3)Script DOM Element、Script Defer、document.write Script Tag
Script DOM Element:允许跨域获取脚本,代码如:
var domsr=document.createElement('script');
domsr.src='1.js';
document.getElementsByTagName('head')[0].appendChild(domsr);
Script Defer:脚本中不包含对document.wirte的调用,且当前页面中没有其它脚本依赖它时,使用这个属性是安全的,只有IE和新浏览器支持这个defer属性。代码:
document.write Script Tag:只有在IE中是并行加载的,代码:
document.write("<script type='text/javascript' src='1.js'><\/script>");
浏览器忙时的指示器:状态栏、进度条、标签页图标、光标、阻塞渲染(差的用户体验)、阻塞onload事件,使用XHR Eval、XHR注入不会触发浏览器的忙指示器,忙指示器是否触发是由技术和浏览器来共同决定的。浏览器忙指示器的目的是让用户知道页面下面运行。
如果下载脚本是并行的,浏览器执行脚本是最先到达的最先执行。并不是按排列顺序执行的,但是document.write Script Tag、script defer、Script DOM Element除外。
没有独立的最佳方案,真正的最佳方案取决于需求。
有六种使用结果:
(1)不同域、无序(2)不同域、保持顺序(3)同域、无序、无忙时指示器(4)同域、无序、有忙时指示器(5)同域、保持顺序、无忙时指示器(6)同域、保持顺序、有忙时指示器