
脚本位置:将js脚本放置在body底部,由于脚本会阻塞页面渲染,导致明显延迟,通常表现为空白页面,用户无法游览页面的内容,也无法与页面进行交互。故因此推荐js脚本放在body底部,尽可能减少对整个页面的下载的影响。
注:内嵌脚本放置在引用外链样式表的<link>标签之后会导致页面堵塞去等待样式表的下载。(原因:为确保内嵌脚本在执行时能获取最精准的页面信息。)
组织脚本:由于每个script标签都会阻塞页面渲染,因为http请求会带来额外的性能开销。
无阻塞的脚本:
- 延迟的脚本:defer和async
- 动态脚本脚本元素:
function loadScript(url,callback){
var script = document.createElement(“script”);
script.type = “text/javascript”;
if(script.readyState){ // IE
script.onreadystatechange = function(){
if(script.readyState == “loaded” || script.readyState == “complete” ){
script.onreadystatechange = null;
callback();
}
};
}else{ //其他游览器
script.onload = function(){
callback();
}
} script.src = url; document.getElementsByTagName(“head”)[0].appendChild(script); }
动态脚本加载凭借在跨游览器兼容性和易用的优势,成为最通用的无阻塞加载解决方案。
- XMLHttpRequest脚本注入
var xhr = new XMLHttpRequest();
xhr.open("get","file.js",true);
xhr.onreadystatechange = function(){
if ( xhr.readyState == 4 ){
if ( xhr.status >= 200 && xhr.status < 300 || xhr.status ==304 ){
var script = document.createElement("script");
script.type = "text/javascript";
script.text = xhr.responseText;
document.body.appendChild(script);
}
}
};
xhr.send(null);
优点:你可以下载js脚本但不立即执行,同时同样的代码在所有主流游览器中均能正常工作。
局限性:js文件必须与所请求的页面处于相同的域。
故推荐使用的无阻塞模式:先添加动态加载所需的代码,然后加载初始化页面所需的剩下的代码。例如
<script type="text/javascript" src="loader.js"></script>
<script type="text/javascript">
loadScript("the-rest.js",function(){
Application.init();
})
</script>
优点:确保js执行过程中不会阻塞页面其他内容的显示;第二个js完成下载时,DOM结构已经创建完毕,并做好了交互的准备,从而避免了需要其他事件来检测页面是否准备好。
另一种方法是把loadScript()函数直接嵌入页面,从而避免多产生一次HTTP请求。