浏览器解析 JavaScript 、CSS 、DOM 时,一般都是单线程解析,所以,引用外部文件时的位置不同,UE体验也不同。
下面是 Yahoo 大牛 Nicholas C. Zakas 的 《High Performance JavaScript》书中的总结。
1、把不影响DOM布局的 JS 文件引用放到 </body> 之前,这样浏览器可先加载HTML页面,解析DOM,给人相对快的感觉。
<html>
<head>
<title></title>
</head>
<body>
...
<script src="jquery.js"></script>
<script src="jqueryui.js"></script>
</body>
</html>
2、动态加载 JS,意思是动态生成<script>标签,加载外部 JS 文件,利用了浏览器解析 DOM 元素的 src 时不阻塞的特性。
一般可在<head></head>标签中动态生成<script>标签,如下,
<head>
<script>
// 加载 JS 的封装函数
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.readState == "complete") {
script.onreadystatechange = null;
// JS 文件加载完之后,可以处理一些事情
callback();
}
}
}
else { // firefox\ chrome \opera
script.onload = function() {
// JS 文件加载完之后,可以处理一些事情
callback();
};
} script.src = url;
document.getElementsByTagName("head")[0].appendChild(script);
} //
loadScript("http://xxx.com/jquery.com", function() { ... }); </script>
</head>
通过以上方法,也可按照顺序加载多个 JS 文件,
loadScript("file1.js", function() {
loadScript("file2.js", function() {
loadScript("file3.js", function() {
// 加载完毕
......
});
});
});
3、使用 LazyLoad.js 开源库以非阻塞方式加载外部 JS 文件,从 github : LazyLoad.js 下载,
<script src="js/lazyload-min.js"></script>
<script>
LazyLoad.js("the-rest.js", function() {
// 加载完之后,做一些逻辑操作
......
});
</script>
也可以同时加载多个 JS 文件,写成数组的形式,
LazyLoad.js(["the-rest.js", "file2.js", "file3.js"], function() {
// 加载完之后,做一些逻辑操作
......
});
注意,LazyLoad 会保证在所有的浏览器中按照顺序加载所有 JS 文件,每一个 JS 文件都是一个单独的 HTTP 请求,
并且全部加载完之后才会执行回调函数 callback。
LazyLoad 也可以用来动态加载 CSS 文件,CSS文件的下载以并行的方式完成,并且不会阻塞其他页面。
4、使用 LAB.js 开源库以非阻塞方式加载外部 JS 文件,从 lab.js 下载,
<script src="js/LAB.min.js"></script>
<script>
$LAB.script("the-rest.js").wait(function() {
// 加载完之后,做一些逻辑操作
......
});
</script>
$LAB 的方法都返回一个 $LAB 对象,所以可以进行链式调用。
$LAB.wait() 方法保证只有等 JS 文件下载并执行完之后,才会执行最终的回调函数。
也可以同时加载多个 JS 文件,
$LAB.script("first.js").script("the-rest.js").wait(function() {
// 加载完之后,做一些逻辑操作
......
});
一般情况下,LAB 会按照顺序执行多个JS 文件,但并不保证,所以,如果你要保证运行的前后顺序,
那么请使用 wait() 方法,如下,
$LAB.script("first.js").wait().script("the-rest.js").wait(function() {
// 加载完之后,做一些逻辑操作
......
});
这样,就可保证 first.js 在 the-rest.js 之前运行。下载的顺序可以并行。