js執行是單線程,並不是說整個瀏覽器都是單線程的,姑且就成為單線程吧
js單線程的原因是為了避免多線程操作dom,引發的並發問題,dom屬於基礎數據,從多線程上講,對它的操作要加事物,而js的操作最初就是為了操作dom,嗯,幸好是單線程的,總之一句話,凡是能夠修改dom的一定得同步
客戶端js時間線
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,瀏覽器創建線程加載,並繼續解析文檔。
async屬性的腳本,腳本加載完成后立即執行。
defter==丟置尾部。
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、從此,以異步響應方式處理用戶輸入、網絡事件等。
當然這條線是理論/規范時間線,瀏覽器具體的操作,誰也管不了(萬惡的ie)
注入為什么要把js放在下面?
ready和load有什么區別?
BigPipe,ajax