一般而言,javascript腳本一般是建議放在body標簽的底部,因為使用script標簽加載js時,會停止加載后面的內容而停下來解析腳本並對頁面進行渲染,使用src屬性加載外部腳本也會造成這樣的情況,這樣的話,如果在head或者body的前面放入過多的script標簽,並且內容很多的時候,會造成頁面在解析完所有script標簽的內容前有短暫的時間整個頁面空白,給用戶的體驗會很差。但是如果所有的腳本都放在底部,又會造成dom加載完畢后有一段時間頁面雖然能看到,但是和用戶的交互卻很差,因此需要讓一些腳本與頁面異步加載。
1.在html5中,script新增了async的屬性,script添加了該屬性之后,下載腳本時將可以與頁面其他內容並行下載,但是該屬性必須在ie9以上的瀏覽器中才可以使用,並且只能用於加載外部js腳本。
2.同樣,在html4中也有一個defer屬性,該屬性的兼容性更好一點,但是與async一樣,可以讓js腳本實現異步加載,同樣只能用於加載外部js腳本。
asyc與defer屬性的不同點是,async會讓腳本在加載完可用時立即執行,而defer腳本則會在dom加載完畢后執行,defer腳本的執行會在window.onload之前,其他沒有添加defer屬性的script標簽之后。
<!DOCTYPE html> <html lang="en"> <head> <title></title> <meta charset="UTF-8"> </head> <script> window.onload = function() { console.log("window.onload"); } </script> <script src="js/defer.js" defer></script> <script> console.log("normal"); </script> <body> </body> </html>
顯示的順序為:normal defer window.onload
3.利用XHR異步加載js內容並執行,代碼如下
<!DOCTYPE html> <html lang="en"> <head> <title></title> <meta charset="UTF-8"> </head> <script> var xhr = new XMLHttpRequest(); xhr.open("get", "js/defer.js",true) xhr.send(); xhr.onreadystatechange = function() { if (xhr.readyState == 4 && xhr.status == 200) { eval(xhr.responseText); } } </script> <body> </body> </html>
4.動態創建script標簽,主要代碼如下
var script = document.createElement("script"); script.src = "js/test.js"; document.head.appendChild(script);
該方式還可以通過script的onreadyState監視加載的狀態。
5.iframe方式,利用iframe加載一個同源的子頁面,讓子頁面內的js影響當前父頁面的一種方式。