Javascript 異步加載詳解(瀏覽器在javascript的加載方式)
2024-05-06 14:22:03
供稿:網友
一、同步加載與異步加載的形式
1. 同步加載
我們平時最常使用的就是這種同步加載形式:
<script src="http://yourdomain.com/script.js"></script>
同步模式,又稱阻塞模式,會阻止瀏覽器的后續處理,停止了后續的解析,因此停止了后續的文件加載(如圖像)、渲染、代碼執行。
js 之所以要同步執行,是因為 js 中可能有輸出 document 內容、修改dom、重定向等行為,所以默認同步執行才是安全的。
以前的一般建議是把<script>放在頁面末尾</body>之前,這樣盡可能減少這種阻塞行為,而先讓頁面展示出來。
簡單說:加載的網絡 timeline 是瀑布模型,而異步加載的 timeline 是并發模型。
2. 常見異步加載(Script DOM Element)
代碼如下:
(function() {
var s = document.createElement('script');
s.type = 'text/javascript';
s.async = true;
s.src = 'http://yourdomain.com/script.js';
var x = document.getElementsByTagName('script')[0];
x.parentNode.insertBefore(s, x);
})();
異步加載又叫非阻塞,瀏覽器在下載執行 js 同時,還會繼續進行后續頁面的處理。
這種方法是在頁面中<script>標簽內,用 js 創建一個 script 元素并插入到 document 中。這樣就做到了非阻塞的下載 js 代碼。
async屬性是HTML5中新增的異步支持,見后文解釋,加上好(不加也不影響)。
此方法被稱為 Script DOM Element 法,不要求 js 同源。
將js代碼包裹在匿名函數中并立即執行的方式是為了保護變量名泄露到外部可見,這是很常見的方式,尤其是在 js 庫中被普遍使用。
例如 Google Analytics 和 Google+ Badge 都使用了這種異步加載代碼:
代碼如下:
(function() {
var ga = document.createElement('script');
ga.type = 'text/javascript'; ga.async = true;
ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
})();
(function()
{var po = document.createElement("script");
po.type = "text/javascript"; po.async = true;po.src = "https://apis.google.com/js/plusone.js";
var s = document.getElementsByTagName("script")[0];
s.parentNode.insertBefore(po, s);
})();
但是,這種加載方式在加載執行完之前會阻止 onload 事件的觸發,而現在很多頁面的代碼都在 onload 時還要執行額外的渲染工作等,所以還是會阻塞部分頁面的初始化處理。
3. onload 時的異步加載
代碼如下:
(function() {
function async_load(){
var s = document.createElement('script');
s.type = 'text/javascript';
s.async = true;
s.src = 'http://yourdomain.com/script.js';
var x = document.getElementsByTagName('script')[0];
x.parentNode.insertBefore(s, x);
}