瀏覽器如何解析html?
這里是瀏覽器加載一個有 標簽的網站發生的事情:
拉取 HTML 頁面 (e.g. index.html)開始解析 HTML解析到 標簽之后準備獲取 script 文件.瀏覽器獲取script文件。同時,html 解析中斷并且阻斷頁面上其他html的解析。一段時間后,script下載完成并且執行。繼續解析HTML文檔的其他部分(解析script之后的html代碼)第4步導致了不好的用戶體驗,直到script文件全部下載完成之前HTML都不能得到解析。
為什么會發生阻斷事件?
任何script代碼都能改變HTML的結構,通過 這種方式或者其他方式。 這就導致了HTML解析必須等待script全部被下載和執行完,HTML才能解析script標簽之后余下的部分。
然而,大部分的Javascript開發者在加載文檔過程中,不會通過script操作HTML的DOM結構。然而,他們必須等到script全部加載結束,才能看到頁面。舉個例子:
Javascript:
因為你的瀏覽器在下載并執行完my-script.js標簽之前,并不知道my-script.js這個文件不會去修改DOM結構,導致HTML停止解析(在script下載并執行完之前)
之前推薦的方法(已過時):
之前解決這個問題的方法是把 標簽放到標簽之后 ,這確保了解析到</body>之前都不會被script終端。
這個方法是有問題的: 瀏覽器在整個文檔解析完成之前都不能下載script文件,如果文檔很大的話,解析完HTML,用戶依然要等待script文件下載并執行完成之后,才能操作這個網站。(主要是串行,先解析HTML完,再下載并執行script,速度肯定沒有并行塊,那么怎么并行呢?我們假設能在解析HTML一開始,就開始下載script,并且不阻斷HTML的解析,是不是就并行了呢)如果你的網站在2秒之內沒有響應,用戶就會跑掉;
現在推薦的解決方案:
現在瀏覽器script標簽支持 和 屬性. 應用這些屬性當script被下載時,瀏覽器更安全而且可以并行下載(下載script并不阻斷HTML解析)。
async
async標記的Script異步執行下載,并執行。這意味著script下載時并不阻塞HTML的解析,并且下載結束script馬上執行。異步意味著,上述代碼script2可能比script1先下載完并執行完。
根據 http://caniuse.com/#feat=script-async, 90% 的瀏覽器支持async屬性.
defer
defer標簽的script順序執行。這種方式也不會阻斷瀏覽器解析HTML。
跟 async不同, defer scripts在整個文檔里的script都被下載完才順序執行。
根據 http://caniuse.com/#feat=script-defer, 90% 的瀏覽器支持這個屬性. 92% 至少部分支持此屬性。
注意:在 IE <= 9 瀏覽器應用defer屬性可能會導致script不會順序執行。如果你想讓低版本IE支持此屬性,請看 this
結論
應用 or 這兩個屬性,擁抱未來。
原答案來自萬能的: stackoverflow