當瀏覽器遇到<script>標籤時,頁面的加載、介些都會停下來,運行此javascript代碼,而後再繼續加載。這種事情一樣會發生在那些以"src"屬性調用的外部腳本,瀏覽器首先下載外部文件的代碼,這要佔用一些時間,而後在運行這些代碼,這又要佔用一些時間。此過程當中,頁面的解析與用戶的交互都是阻塞的。javascript
無論是內聯腳本仍是外部腳本,都應該儘可能放在<body>
標籤結束以前(除非某些腳本須要在頁面加載完以前調用),這樣能夠保證在運行腳本以前,頁面已經基本加載完成。java
延時腳本
能夠給script
標籤添加一個屬性 - defer ,這個屬性代表:元素中的腳本不打算修改DOM,所以代碼能夠稍後執行。帶有這個屬性的任何script
元素中的腳本都不會在DOM加載完以前執行,若是是外部腳本,這些腳本首先並行下載,而不會執行,因此不會阻塞頁面的加載。實例代碼以下:<script src="./script/file1.js" defer>
瀏覽器
動態腳本元素
DOM容許你經過腳原本建立script
元素,像下面這樣:app
var script = document.createElement("script"); script.type = "text/javascript"; script.src = "./script/file1.js"; document.getElementsByTagName("head")[0].appendChild(script);
此文件元素添加到頁面後當即開始下載。此技術的重點在於:不管在何處啓動下載,腳本的下載和運行都不會阻塞頁面的處理過程。
爲方便使用,我整合了一個動態加載腳本的方法:url
function loadJS(url, callback) { var script = document.creatElement("script"); script.type = "text/script"; if(script.readyState) { script.onreadystatechange = function() { if(script.readyState == "loaded" || script.readyState == "complete") { script.onreadystatechange = null; callback; } }; }else { script.onload = function() { callback(); }; } script.src = url; document.getElementsByTagName("head")[0].appendChild(script); }
XMLHttpRequest 腳本注入
另外一個以非阻塞的方式得到腳本的方法是使用XHR對象將腳本注入到頁面中。此技術先建立一個XHR對象,而後下載腳本文件,接着用一個動態的script
元素將javascript代碼注入頁面:code
var xhr = new XMLHttpRequest(); xhr.open("get", "./scripts/file1.js", true); xhr.onreadystatechange = function(){ if(xhr.readyState == 4) { if(xhr.status >= 200 && xhr.status < 300 || xhr.status == 400) { var script = document.createElement("script"); script.type = "text/javascript"; script.text = xhr.responseText; document.body.appendChild(script); } } }; xhr.send(null); };
此方法的限制是,你必須下載同一個域下的文件,不能從CDN下載。對象