腳本位置
由于腳本會阻塞頁面其他資源的下載, 因此推薦將所有的< script >標(biāo)簽盡可能放到< body >標(biāo)簽的底部, 以盡量減少對整個頁面下載的影響.
組織腳本
- Steve Souders發(fā)現(xiàn), 把一段內(nèi)嵌腳本放在引用外鏈樣式表的< link >標(biāo)簽之后會導(dǎo)致頁面阻塞去等待樣式表的下載. 這樣做是為了確保內(nèi)嵌腳本在執(zhí)行時能獲得最精確的樣式信息. 因此, Souders建議永遠不要把內(nèi)嵌腳本緊跟在< link >標(biāo)簽的后面.
- 考慮到HTTP請求會帶來額外的性能開銷, 因此下載單個100KB的文件要比下載4個25KB的文件更快. 也就是說, 減少頁面中外鏈腳本文件數(shù)量將會改善性能.
延遲的腳本
HTML4為< script >標(biāo)簽定義了一個擴展屬性: defer.
<script type="text/javascript" src="1.js" defer></script>
HTML5規(guī)范還引入了async屬性, 用于異步加載腳本. async與defer的相同點是采用并行下載. 在下載過程中不會產(chǎn)生阻塞. 區(qū)別在于執(zhí)行時機, async是加載完成后自動執(zhí)行, 而defer需要等待頁面完成后執(zhí)行.
帶有defer屬性的< script >標(biāo)簽可以擺放在文檔的任何位置. 對應(yīng)的javascript文件將在頁面解析到< script >標(biāo)簽時開始下載, 但并不會執(zhí)行, 知道DOM加載完成(onload事件被觸發(fā)前). 當(dāng)一個帶有defer屬性的javascript文件下載時, 它不會阻塞瀏覽器的其他進程, 因此這類文件可以與頁面中的其他資源并行下載.
動態(tài)腳本元素(即使用js插入的外部js文件)
使用動態(tài)腳本節(jié)點下載文件時, 返回的代碼通常會立刻執(zhí)行(除了Firefox和Opera, 它們會等待此前所有動態(tài)腳本節(jié)點加載完成), 但是當(dāng)代碼只包含供頁面其他腳本調(diào)用的接口時, 就會有問題. 在這種情況下, 你必須跟蹤并確保腳本下載完成且準(zhǔn)備就緒.
封裝的函數(shù):
function loadScript(url, callback) {
var script = document.createElement('script');
script.type = "text/javascript";
if (script.readyState) {
script.onreadystatechange = function() { //ie
if (script.readyState == 'complete' || script.readyState == 'loaded') {
callback(); //某個函數(shù)
}
}
} else {
script.onload = function() {
callback();
}
}
script.src = url;
document.head.appendChild(script);
}
推薦的無阻塞模式
<script type="text/javascript" src="loader.js"></script>
<script type="text/javascript">
loadScript("1.js", function(){
Application.init();
})
</script>
第一部分(例 : loader.js)代碼盡量精簡, 甚至可能只包含loadScript( )函數(shù)
或者也可以把loadScript( )函數(shù)直接嵌入在頁面, 然后調(diào)用loadScript()函數(shù)插入其它文件.