一、script標簽的位置
傳統的做法是:所有script元素都放在head元素中,必須等到全部js代碼都被下載、解析、執行完畢后,才能開始呈現網頁的內容(瀏覽器在遇到<body>標簽時才開始呈現內容),這在需要很多js代碼的頁面來說,會造成瀏覽器在呈現頁面時出現明顯的延遲,而延遲期間的瀏覽器窗口將是一片空白。因此。一般把script標簽放在</body>標簽前面。
二、嵌入腳本與外部腳本
盡可能使用外部腳本,理由如下:
(1)將所有js文件放在一個文件夾中,再不觸及HTML代碼的情況下編輯js文件,便於維護。
(2)瀏覽器可以根據具體的設置所有外部js文件,同一個文件只需下載一次,可以加快頁面加載的速度。
三、async和defer
1、defer="defer"和async="true/false"
html4.0中定義了defer;html5.0中定義了async。
(1)沒有defer或async,瀏覽器會立即加載並執行指定的JS腳本,也就是說,不等待后續載入的文檔元素,讀到JS腳本就加載並執行。
(2)有async,加載后續文檔元素的過程將和JS的加載與執行並行進行(異步)。
(3)有defer,加載后續文檔元素的過程將和JS的加載並行進行(異步),但JS的執行要在所有文檔元素解析完成之后,DOMContentLoaded 事件觸發之前完成。
2、defer和async的共同點:
(1)不會阻塞文檔元素的加載。
(2)使用這兩個屬性的腳本中不能調用document.write方法。
(3)允許不定義屬性值,僅僅使用屬性名。
(4)只適用於外部腳本(雖然IE4-IE7還支持對嵌入腳本的defer屬性,但在IE8及之后的版本就只支持外部腳本,對不支持的會直接忽略defer屬性,因此把延遲腳本放在頁面底部仍然是最佳選擇)。
3、defer和async的不同點:
(1)每一個async屬性的腳本一旦加載完畢就會立刻執行,一定會在window.onload之前執行,但可能在document的DOMContentLoaded之前或之后執行。不保證按照指定它們的順序來執行,如果JS有依賴性就要注意了。指定異步腳本的目的是不讓頁面等待兩個腳本下載和執行,從而異步加載頁面其他內容,因此,建議異步腳本不要在加載期間修改DOM。
(2)每一個defer屬性的腳本都是在文檔元素完全載入后,一般會按照原本的順序執行,同時一般會在document的DOMContentLoaded之前執行,相當於window.onload,但應用上比 window.onload 更靈活!實際上,defer 更接近於DomContentLoad。事實上,延遲腳本不一定會按順序執行,也不一定會在DOMContentLoaded事件觸發之前執行,因此最好只包含一個延遲腳本。
四、動態創建script
在沒有定義defer和async之前,異步加載的方式是動態創建script,通過window.onload方法確保頁面加載完畢再將script標簽插入到DOM中。
-
function addScriptTag(src){
-
var script = document.createElement('script');
-
script.setAttribute("type","text/javascript");
-
script.src = src;
-
document.body.appendChild(script);
-
}
-
window.onload = function(){
-
addScriptTag("js/index.js");
-
