async與defer的作用與區別以及阻塞優化

五公里發表於2019-05-08

async和defer的作用是什麼?有什麼區別?

1. 在瀏覽器在渲染時,在html檔案中讀取到js檔案,會立即停止渲染,執行JS程式碼,如果沒有 defer屬性 或 async屬性,會等script檔案下載執行完後才繼續渲染。
2. <script async src="script.js"></script>(非同步下載)會下載指令碼,但是不會立即執行,並且不一定按照script順序觸發;這種方式載入的 JavaScript 依然會阻塞 load 事件。換句話說,async可能在 DOMContentLoaded 觸發之前或之後執行,但一定會在 load 觸發之前執行。
  • (1)HTML5屬性;Chorme,FireFox,IE9+瀏覽器支援
  • (2)async屬性僅適用於外部指令碼
  • (3)執行順序是不確定的
  • (4)async 屬性表示非同步執行引入的 JavaScript
  • (5)與 defer 的區別在於,如果已經載入好,就會開始執行,無論此刻是 HTML 解析階段還是 DOMContentLoaded 觸發之後
3. <script defer src="script.js"></script>(延遲執行)是否對指令碼執行延遲,直到頁面載入為止
(1). 相容所有瀏覽器
(2). defer 與相比普通 script,有兩點區別:載入 JavaScript 檔案時不阻塞 HTML 的解析,執行階段被放到HTML標籤解析完成之後;
(3). 如果指令碼不改變文件的內容,可以用defer屬性,以便加快處理文件速度
(4).defer 屬性表示延遲執行引入的 JavaScript,即這段 JavaScript 載入時HTML 並未停止解析,這兩個過程是並行的
(5).defer 不會改變 script 中程式碼的執行順序,整個 document 解析完畢且 defer-script 也載入完成之後(這兩件事情的順序無關),會執行所有由 defer-script 載入的JavaScript 程式碼,然後觸發 DOMContentLoaded 事件。
(6)所有設定了defer屬性的指令碼按順序執行,async是無順序的載入
(7)無論設定了defer或async,該script會在onload前執行;
(8)IE/chrome在設定defer時,與firefox不同,前者會等指令碼執行後才執行DOMContentLoaded;而後者會先於指令碼執行
  • script指令碼阻塞有什麼解決方法?(script非同步載入的四種方式)
(1)引入jquery
$(document).ready(function(){
內容

})
複製程式碼
(2)async屬性
(3)defer屬性
(4)動態建立<script>標籤(相容所有瀏覽器)
 (function(){
	 var script =document.createElement('script');
	 script.type='text/javascript';
	 script.src="http://code.jquery.com/jquery-1.7.2.min.js";
	 var tmp=document.getElementsByTagName('script')[0],
	tem.parentNode.insertBefore(script,tmp);
 })
複製程式碼
  • css阻塞有什麼解決方法?
css的載入並不會導致html解析和渲染的停止,但是會影響到js指令碼的執行。因為js指令碼不僅可以讀取修改到dom,也可以讀取修改到cssom。故在js指令碼執前,browser必須保證到css檔案完全載入並解析完成,即cssom樹完全構建好。這就導致了js執行的延遲,也因此導致html解析和渲染延遲。(這就是css阻塞js執行,阻塞渲染的根本原因)

因此一些解決方法:

  • 1、在引入順序上,css資源的引入要優於js指令碼的引入
  • 2、對css進行精簡併儘快提供
  • 3、可以用媒體型別(會載入不會阻塞)
  • 4、用媒體查詢(會記載,只有在符合的裝置上才會進行阻塞)

參考文章:

相關文章