本文轉載自 Glimis, https://www.cnblogs.com/liuCy/p/4362857.html
1、創建document對象,開始解析web頁面。創建HTMLHtmlElement對象,添加到document中。這個階段document.readyState = 'loading';
2、遇到link外部css,創建線程加載,並繼續解析文檔。並發;
3、遇到script外部js,並且沒有設置async、defer,瀏覽器創建線程加載,並阻塞,等待js加載完成並執行該腳本,然后繼續解析文檔。js擁有修改dom的能力-->domcument.write;
4、遇到script外部js,並且設置有async、defter,瀏覽器創建線程加載,並繼續解析文檔;
defer屬性設置后,表示加載script外部js和解析html頁面是異步,並且等到html解析完成再執行js解析后的代碼;
async屬性設置后,表示加載script外部js和解析html頁面是異步,但是當js解析完成,立刻執行它,此時html解析是被阻塞的;
document.createElement('script')的方式動態插入script元素來模擬async屬性,實現腳本異步加載和執行;
5、遇到img等,瀏覽器創建線程加載,並繼續解析文檔。並發;
6、當文檔解析完成,document.readyState = 'interactive';
7、文檔解析完成后,所有設置有defer的腳本會按照順序執行(注意與async的不同);
8、document對象觸發DOMContentLoaded事件,這也標志着程序執行從同步腳本執行階段,轉化為事件驅動階段;
9、當所有async的腳本加載完成並執行后、img等加載完成后,document.readyState = 'complete',window對象觸發load事件;
10、從此,以異步響應方式處理用戶輸入、網絡事件等。