如何用最高效的方式把javascript代碼加載到頁面中呢懂更?
1眨业、腳本位置
每個文件必須等到前一個文件下載并執(zhí)行完成才會開始下載。在這些文件逐個下載過程中沮协,用戶看到的是一片空白龄捡。稱為腳本阻塞。因此推薦將所有的標(biāo)簽盡可能放到標(biāo)簽的底部慷暂,以盡量減少對整個頁面下載的影響聘殖。
<html>
<head>
<title>script example</title>
<link rel="stylesheet" type="text/css" href="style.css">
</head>
<body>
<p>Hello world!</p>
<!-- 推薦的腳本存放位置 -->
<script type="text/javascript" src="file1.js"></script>
<script type="text/javascript" src="file2.js"></script>
<script type="text/javascript" src="file1.js"></script>
</body>
</html>
2晨雳、組織腳本
(1)瀏覽器在解析HTML頁面的過程中,每遇到一個<script>標(biāo)簽奸腺,都會因執(zhí)行腳本而導(dǎo)致一定的延時餐禁,所以減少頁面所包含的<script>標(biāo)簽數(shù)量有助于改善頁面性能。
(2)HTTP請求會帶來額外的性能開銷突照,因此下載單個100KB的文件將比下載4個25KB的文件更快帮非。即,減少頁面中外鏈腳本文件的數(shù)量將會改善性能讹蘑。
綜述:用文件打包工具把多個文件合并成1個末盔,這樣只需要引用一個<script>標(biāo)簽,就可以減少性能消耗座慰。
<html>
<head>
<title>script example</title>
<link rel="stylesheet" type="text/css" href="style.css">
</head>
<body>
<p>Hello world!</p>
<!-- 推薦的腳本存放位置 -->
<script type="text/javascript" src="file1.js"></script>
</body>
</html>
3陨舱、無阻塞的腳本
秘訣:在頁面加載完成后才加載JavaScript代碼。
(1)延遲的腳本
帶有defer屬性的JavaScript文件將在頁面解析到<script>標(biāo)簽時開始下載版仔,但并不會執(zhí)行游盲,下載時,不會阻塞瀏覽器的其他進程蛮粮,可以與頁面中其他資源并行下載益缎。它下載完成后,在onload事件被觸發(fā)前執(zhí)行然想。
該屬性只有IE4+ 和 firefox3.5+ 的瀏覽器支持链峭。
<head>
<title>script defer example</title>
<link rel="stylesheet" type="text/css" href="style.css">
</head>
<body>
<script defer>
alert("defer");
</script>
<script>
alert("script");
</script>
<script>
window.onload = function(){
alert("load");
}
</script>
</body>
</html>
<small>該 示例 在支持defer屬性的瀏覽器上,彈出的順序是:script , defer , load.</small>
(2)動態(tài)腳本文件
該腳本文件被添加到頁面時開始下載又沾,無論在何時啟動下載,文件的下載和執(zhí)行過程不會阻塞頁面其他進程熙卡。
<html>
<head>
<title>動態(tài) script example</title>
</head>
<body>
<script>
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.getElementByTagName("head")[0].appendChild(script);
}
loadScript("file1.js" , function(){
alert("file is loaded 杖刷!");
})
</script>
</body>
</html>
<small>該 示例 用到<script>的readyState屬性,該屬性有5種取值:
uninitialized 初始狀態(tài)
loading 開始下載
loaded 下載完成
interactive 數(shù)據(jù)完成下載但尚不可使用
complete 所有數(shù)據(jù)已準(zhǔn)備就緒</small>
(3)XMLHttpRequest(xhr對象) 腳本注入
優(yōu)點1:你可以把腳本的執(zhí)行推遲到你準(zhǔn)備好的時候驳癌。
優(yōu)點2:在所有主流瀏覽器都能正常使用滑燃。
缺點:JavaScript文件必須與所請求的頁面屬于相同的域。
<html>
<head>
<title>xhr script example</title>
</head>
<body>
<script>
var xhr = new XMLHttpRequest();
xhr.open("get" , "file1.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);
</script>
</body>
</html>
<small>這段代碼發(fā)送一個get請求獲取file1.js文件颓鲜。事件處理函數(shù)onReadyStateChange 檢查readyState 是否為4 表窘,同時校驗HTTP狀態(tài)碼是否有效(2XX 表示有效響應(yīng),304意味著是從緩存讀忍鸨酢)乐严。如果收到了有效響應(yīng),就會創(chuàng)建一個<script>元素衣摩,設(shè)置該元素的text屬性為從服務(wù)器接收到的responseText昂验。</small>
(4)作者推薦的無阻礙模式
- 第一種:YUI3的方式
YUI3 API:https://github.com/yui/yui3
設(shè)計理念:由頁面中的少量代碼來加載豐富的功能組件。
<html>
<head>
<title>YUI3 example</title>
</head>
<body>
<script src="http://yui.yahooapis.com/3.18.1/build/yui/yui-min.js"></script>
<script>
// Create a YUI sandbox on your page.
YUI().use('node', 'event', function (Y) {
// The Node and Event modules are loaded and ready to use.
// Your code goes here!
});
</script>
</body>
</html>
- 第二種:LazyLoad類庫
LazyLoad源文件代碼:http://github.com/rgrove/lazyload/
<html>
<head>
<title>LazyLoad example</title>
</head>
<body>
<script type="text/javascript" src="lazyload.js"></script>
<script>
LazyLoad.js("the-rest.js",function(){
Application.init();
});
</script>
</body>
</html>
- 第三種:LABjs
LazyLoad源文件代碼:https://github.com/getify/LABjs
特點:通過wait()管理依賴關(guān)系
<html>
<head>
<title>LABjs example</title>
</head>
<body>
<script type="text/javascript" src="LAB.js"></script>
<script>
$LAB.script("first-file.js").wait()
.script("the-rest.js")
.wait(function(){
Application.init();
});
</script>
</body>
</html>
<small>在前面的例子中,不能保證first-file.js的代碼在the-rest.js的代碼前執(zhí)行既琴。
為了確保這一點占婉,你必須在第一個script()方法后調(diào)用wait(),比如甫恩,
如下示例可以保證first-file.js的代碼在the-rest.js的代碼前執(zhí)行逆济。</small>
<html>
<head>
<title>LABjs example</title>
</head>
<body>
<script type="text/javascript" src="LAB.js"></script>
<script>
$LAB.script("first-file.js").wait()
.script("the-rest.js")
.wait(function(){
Application.init();
});
</script>
</body>
</html>