執行外部腳本的方法:
1. 如果 async="async":腳本相對於頁面的其餘部分異步地執行(當頁面繼續進行解析時,腳本將被執行)
2.如果不使用 async 且 defer="defer":腳本將在頁面完成解析時執行
3.如果既不使用 async 也不使用 defer:在瀏覽器繼續解析頁面之前,立即讀取並執行腳本
阻塞特性:
如果既不使用 async 也不使用 defer,當瀏覽器在執行JS 代碼時,不能同時做其他任何事情,無論其代碼是內嵌的還是外部的。
腳本位置:
瀏覽器在碰到一個引入外部JS 文件的<script>標籤時會停下所有工作來下載並解析執行它,在這個過程中,頁面渲染和用戶交互完全被阻塞了,爲了避免頁面加載時的停頓甚至空白頁的出現,JS 腳本應儘量放置在頁面底部。
<html>
<head>
<title></title>
<!-- 這裏順便說一下,推薦把css文件放在head裏,因爲頁面渲染需要css -->
<link rel="stylesheet" type="text/css" href="styles.css" />
</head>
<body>
<p>頁面內容</p>
<!-- 推薦把js放在頁面底部: -->
<script type="text/javascript" src="file.js"></script>
</body>
</html>
組織腳本:
爲了改善上面的阻塞情況,應儘可能的減少頁面中<script>標籤的出現次數,這同時也是考慮到HTTP 請求會帶來額外的性能開銷,也就是說應減少頁面中外鏈腳本的數量。也可以手動合併你的多個JS 文件,也可採用類似Yahoo! combo handler 這樣的實時在線服務來實現,例如下面的這個<script>標籤實際上便載入了3個JS 文件:
<script type="text/javascript" src="http://yui.yahooapis.com/combo?file1.js&file2.js&file3.js"></script>
無阻塞的腳本:
爲了阻塞狀況,這裏提供了幾個實現並行下載JS 腳本的方案。
1. 延遲的腳本
HTML4 爲<script>標籤定義了一個defer 屬性,它能使這段代碼延遲執行,然而該屬性只有IE4+ 和Firefox 3.5+ 支持。聲明瞭defer 屬性的<script>會在DOM加載完成,window.onload 事件觸發前被解析執行:
<script type="text/javascript" src="file.js" defer></script>
2. 動態腳本元素
通過DOM 動態地創建<script>元素並插入到文檔中,文件在該元素被添加到頁面時開始下載,這樣 無論在何時啓動下載,文件的下載和執行過程不會阻塞頁面其他進程。不過要注意使用這種方式加載的代碼會立刻執行,這樣需清楚的瞭解各文件的作用以及合理的執行順序,此時跟蹤並確保腳本下載完成並準備就緒是很有必要的,非IE瀏覽器會在<script>元素接收完成時觸發一個load 事件,而IE 下則會觸發一個readystatechange 事件並通過readyState 屬性加以判斷便可。以下是兼容地動態加載一個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.readyState == 'complete') {
script.onreadystatechange = null;
callback();
}
}
} else { //others
script.onload = function() {
callback();
}
}
script.src = url;
document.getElementsByTagName('head')[0].appendChild(script);
}
也可以將loadScript() 的執行串聯起來:loadScript('file1.js', function() {
loadScript('file2.js', function() {
loadScript('file3.js', function() {
//全部載入後的操作...
} );
} );
} );
3. XMLHttpRequest 腳本注入
即通過AJAX 方式加載,不過這種方式無法實現跨域加載,不適用於大型網站。