之前有寫過HTML頁面渲染過程,知道了JavaScript是會阻塞DOM解析的,所以我們會把script標籤放到底部防止阻塞HTML解析。其實script還有兩個屬性,async和defer,也是可以使得JavaScript和DOM和css同步載入。
說著兩個屬性之前先簡單說一下DOMContentLoaded和load。
DOMContentLoaded:DOM內容載入完畢,頁面會展示內容,但是圖片、音視訊等資源還未載入就觸發DOMContentLoaded事件。
Load:在DOMContentLoaded觸發之後觸發,這時候圖片、音視訊等資源也已經載入完畢了。
知道了這兩個事件之後,我們來說說async和defer。這兩個都是用來控制外部指令碼檔案的,就是使用script引入,有src屬性,在script標籤沒有src屬性的內聯指令碼是無效的。這兩個都不會阻塞HTML的解析。
Defer:開啟新的執行緒下載指令碼,使HTML解析完成後執行。如果多個指令碼同時生命defer,會按順序下載和執行,同時會在DOMContentLoaded和load之前執行。意思就是如果HTML解析完成了,指令碼還沒載入完成,那麼一定會等指令碼載入完成了才觸發DOMContentLoaded。(網上有說defer也不一定按順序,這個不知道什麼情況下不按順序)
Async:H5新增屬性,也是用於非同步載入指令碼,下載完畢立即執行。有多個指令碼使用async的時候,不能保證順序,如果指令碼直接有依賴,是不能使用這個屬性。Async會在load之前執行,但是不保證和DOMContentLoaded的執行順序。
另外說一個跟HTML渲染的小知識點,我們在網路很卡的情況下,標籤出來了,樣式沒有出來,之前說的是DOM和css構建出render樹才能渲染頁面,然後就覺得很矛盾,突然看見有文章說現代瀏覽器為了更好的使用者體驗,渲染引擎儘快渲染內容,現在已經不會等所有HTML解析之前開始構建和佈局render樹,部分內容將提前渲染,就是說並不是一定要DOM和css都解析載入完成構建render樹之後才渲染頁面。
歡迎關注Coding個人筆記 公眾號