摘要:阻塞原理瀏覽器內核可以分成兩部分渲染引擎或者和引擎。等引擎運行完畢,瀏覽器又會把控制權還給渲染引擎,繼續和的構建。執行時,解析暫停。從加載完成立即執行來看,模式執行順序與寫的順序無關,不保證執行順序。
js阻塞原理
瀏覽器內核可以分成兩部分:渲染引擎(Layout Engine 或者 Rendering Engine)和 JS 引擎。早期渲染引擎和 JS 引擎并沒有十分明確的區分,但隨著 JS 引擎越來越獨立,內核也成了渲染引擎的代稱(下文我們將沿用這種叫法)。渲染引擎又包括了 HTML 解釋器、CSS 解釋器、布局、網絡、存儲、圖形、音視頻、圖片解碼器等等零部件。
JS 引擎是獨立于渲染引擎存在的。我們的 JS 代碼在文檔的何處插入,就在何處執行。當 HTML 解析器遇到一個 script 標簽時,它會暫停渲染過程,將控制權交給 JS 引擎。JS 引擎對內聯的 JS 代碼會直接執行,對外部 JS 文件還要先獲取到腳本、再進行執行。等 JS 引擎運行完畢,瀏覽器又會把控制權還給渲染引擎,繼續 CSSOM 和 DOM 的構建。 因此與其說是 JS 把 CSS 和 HTML 阻塞了,不如說是 JS 引擎搶走了渲染引擎的控制權。
渲染引擎碰到js就交出大權是因為他不知道js的內容會不會對接下來的渲染有沒有影響。但是我們引入js的時候是知道有沒有影響的,可以根據具體情況用三種方式之一加載js。
JS的三種加載方式js 有三種加載方式。
正常模式
沒有 defer 或 async,瀏覽器會立即加載并執行指定的腳本,“立即”指的是在渲染該 script 標簽之下的文檔元素之前,也就是說不等待后續載入的文檔元素,讀到就加載并執行。
async模式
有 async,script.js會被異步加載,即加載和渲染后續文檔元素的過程將和 script.js 的加載并行進行(異步)。當 script.js加載完整立即執行script.js。執行script.js時,html解析暫停。
從加載完成立即執行來看,async模式 執行順序與寫的順序無關,不保證執行順序。
defer 模式
有 defer,script.js會被異步加載,即加載和渲染后續文檔元素的過程將和 script.js 的加載并行進行(異步)。這一點與async模式一致。
不同的是當 script.js加載完成并不會立即執行,而是在所有元素解析完成之后,DOMContentLoaded 事件觸發之前完成。因此它會按照寫的順序執行。
一圖勝千言: 原圖地址
來個demo// htmldefer-async warp
然后 async1.js 文件巨大(到底有多大,我是把jquery的壓縮版拷進來了),然后最后加上 console.log("async1");
文件async2.js 和 normal.js 中分別是 console.log("async2"); 和 console.log("normal");
打開網頁控制臺顯示如下: async2 先加載完成就先執行了。
而當我把 前面引用換成defer時
同理,defer1.js 里放了jquery的壓縮版源碼。defer2.js里只放了一句日志; 刷新網頁看下日志:
defer1 、defer2還是按照順序執行的。
把async、defer都加上,
日志如下:
這個順序應該不是固定的,符合normal最早,defer1會在 defer2之前的規矩。 至于async 和 defer的前后則要看本身js的加載以及dom樹的構建時機吧。
growingwiththeweb 推薦優先級依次是 async defer normal。。
當你的js是個獨立的模塊且不依賴任何js,使用 async;
如果你的js依賴其他js或者被其他js 依賴,使用 defer;
如果你對js文件很小且被 async script 依賴,使用正常模式的script且放在async script 前面。
可能的坑雖然理論上defer按加載順序執行,但也有同學反映事實上并不是這樣。。比如這位同學的問題:
我認為這是涉及到 event loop的 task和微任務了。
"在現實當中,延遲腳本并不一定會按照順序執行,也不一定會在 DOMContentLoaded 事件觸發前執行,因此最好只包含一個延遲腳本。" 《JavaScript 高級程序設計(第三版)》如是說,所以腳本之間有依賴,最好使用一個異步腳本吧。比如上面同學那個問題 可以改成這樣.
掘金小冊
async vs defer
談談script標簽
defer async區別
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/99709.html
摘要:由于始終沒有還原阻塞時的情形,無法截圖。寫模擬場景,由于當時的場景是外鏈是加載阻塞,而不是執行阻塞,暫時沒有有效模擬。但是可以確定的是,使用或可以有效解決,外鏈阻塞內部執行的問題。 由于始終沒有還原阻塞時的情形,無法截圖。在正常情況下,是無法區別是否使用defer的區別的。后續看一下是否能模擬場景。寫demo模擬場景,由于當時的場景是外鏈是js加載阻塞,而不是js執行阻塞,暫時沒有有效...
摘要:修改瀏覽器渲染因為的阻塞使得解析停止,下載完成之前,頁面無法顯示任何東西。瀏覽器渲染解析到文件時出現阻塞。我們把調整到尾部瀏覽器渲染這是頁面可以渲染了,但是沒有樣式。 本文示例源代碼請戳github博客,建議大家動手敲敲代碼。 前言 瀏覽器渲染頁面的過程 從耗時的角度,瀏覽器請求、加載、渲染一個頁面,時間花在下面五件事情上: DNS 查詢 TCP 連接 HTTP 請求即響應 服務器響...
摘要:修改瀏覽器渲染因為的阻塞使得解析停止,下載完成之前,頁面無法顯示任何東西。瀏覽器渲染解析到文件時出現阻塞。我們把調整到尾部瀏覽器渲染這是頁面可以渲染了,但是沒有樣式。 本文示例源代碼請戳github博客,建議大家動手敲敲代碼。 前言 瀏覽器渲染頁面的過程 從耗時的角度,瀏覽器請求、加載、渲染一個頁面,時間花在下面五件事情上: DNS 查詢 TCP 連接 HTTP 請求即響應 服務器響...
閱讀 2434·2021-11-15 11:36
閱讀 1172·2019-08-30 15:56
閱讀 2243·2019-08-30 15:53
閱讀 1038·2019-08-30 15:44
閱讀 649·2019-08-30 14:13
閱讀 997·2019-08-30 10:58
閱讀 476·2019-08-29 15:35
閱讀 1293·2019-08-29 13:58