- defer和asnyc(只對外部文件有效)
- defer 在頁面完成解析時執(zhí)行代碼,這個屬性表明腳本在執(zhí)行時不會影響頁面的構(gòu)造杆融,在元素中設置這個屬性相當于告訴瀏覽器立即下載但延遲執(zhí)行
- async 相對于頁面其他部分異步執(zhí)行腳本,一般的script標簽都是會阻塞頁面執(zhí)行的领突,沒有加上async屬性的標簽會阻塞后面的標簽的解析材彪。一般用在不需要操作dom元素的腳本上,例如一些統(tǒng)計代碼(跟頁面執(zhí)行邏輯無關的挪凑,不涉及dom操作的),可以避免因長時間加載而呈現(xiàn)白屏現(xiàn)象
- script中有或沒有它們的區(qū)別
- script中沒有defer和async逛艰,會立刻加載并執(zhí)行
- script中有async沒有defer時躏碳,會與渲染后續(xù)文檔元素并行加載,加載完自動執(zhí)行
- script中有defer沒有async時散怖,后續(xù)文檔元素渲染會與腳本文件加載并行菇绵,但是執(zhí)行所有元素解析完成之后,在DOMContentLoaded之前執(zhí)行
https://segmentfault.com/q/1010000000640869 這個回答很棒
- 但是紅寶書中有這樣一句話:HTML5規(guī)范要求腳本執(zhí)行應該按照腳本出現(xiàn)的先后順序執(zhí)行镇眷,但在現(xiàn)實生活中咬最,延遲腳本并不一定按照順序執(zhí)行,也不一定會在DOMContentLoaded事件中觸發(fā)前執(zhí)行欠动,因此最好只包含一個延遲腳本永乌。因此上圖第三點說法有欠缺
未解決問題:所有瀏覽器都兼容,那么為什么沒有看到別人在用呢具伍?
查了一下翅雏,網(wǎng)易有在用,瀏覽器兼容還是有點小問題人芽,and業(yè)務需求
- script是可以并行下載的望几,這里應該是指放在head中的script標簽,不會阻塞其他script標簽啼肩,但是仍然會阻塞其他資源下載橄妆,例如圖片衙伶。盡管腳本的下載過程中不會相互影響,但頁面仍然要等到所有js代碼下載并完成執(zhí)行才能繼續(xù)害碾。-- 《高性能的js》
并行下載測試
- 建議放在body的底部
- 每個script標簽初始化都會阻塞頁面渲染矢劲,在解析html頁面過程中每遇到一個script標簽都會因執(zhí)行腳本而導致一定的延時
- 盡管單個較大的js文件只請求一次http,但是這樣會導致鎖死瀏覽器一段時間慌随,解決方案除了上面所說的defer之外還可以動態(tài)創(chuàng)建標簽加入head中芬沉,可以通過onload事件來監(jiān)聽腳本加載是否完畢,ie下通過readystatechange事件
function loadScript(url, callback) {
var script = document.createElement('script');
if ( script.readyState ) { // IE
script.onreadystatechange = function(){
if( script.readyState == "loaded" || script.readyState == "complete") {
script.onreadystatechange = null; // 同時檢查兩種狀態(tài)阁猜,只要有一種觸發(fā)就刪除事件處理器丸逸,避免觸發(fā)兩次
callback();
}
}
}else{
script.onload = function(){
callback();
}
}
script.src = url;
document.getElementsByTagName('head')[0].appendChild(script);
}