国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

拒絕js阻塞—defer、async作用和區別分析

wuaiqiu / 1961人閱讀

摘要:阻塞原理瀏覽器內核可以分成兩部分渲染引擎或者和引擎。等引擎運行完畢,瀏覽器又會把控制權還給渲染引擎,繼續和的構建。執行時,解析暫停。從加載完成立即執行來看,模式執行順序與寫的順序無關,不保證執行順序。

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
// html 



    
    
    
    defer-async

    
    
    


    
warp

然后 async1.js 文件巨大(到底有多大,我是把jquery的壓縮版拷進來了),然后最后加上 console.log("async1");
文件async2.jsnormal.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

相關文章

  • Sdk加載阻塞頁面渲染問題的總結

    摘要:由于始終沒有還原阻塞時的情形,無法截圖。寫模擬場景,由于當時的場景是外鏈是加載阻塞,而不是執行阻塞,暫時沒有有效模擬。但是可以確定的是,使用或可以有效解決,外鏈阻塞內部執行的問題。 由于始終沒有還原阻塞時的情形,無法截圖。在正常情況下,是無法區別是否使用defer的區別的。后續看一下是否能模擬場景。寫demo模擬場景,由于當時的場景是外鏈是js加載阻塞,而不是js執行阻塞,暫時沒有有效...

    AlphaGooo 評論0 收藏0
  • 瀏覽器渲染機制

    摘要:修改瀏覽器渲染因為的阻塞使得解析停止,下載完成之前,頁面無法顯示任何東西。瀏覽器渲染解析到文件時出現阻塞。我們把調整到尾部瀏覽器渲染這是頁面可以渲染了,但是沒有樣式。 本文示例源代碼請戳github博客,建議大家動手敲敲代碼。 前言 瀏覽器渲染頁面的過程 從耗時的角度,瀏覽器請求、加載、渲染一個頁面,時間花在下面五件事情上: DNS 查詢 TCP 連接 HTTP 請求即響應 服務器響...

    FullStackDeveloper 評論0 收藏0
  • 瀏覽器渲染機制

    摘要:修改瀏覽器渲染因為的阻塞使得解析停止,下載完成之前,頁面無法顯示任何東西。瀏覽器渲染解析到文件時出現阻塞。我們把調整到尾部瀏覽器渲染這是頁面可以渲染了,但是沒有樣式。 本文示例源代碼請戳github博客,建議大家動手敲敲代碼。 前言 瀏覽器渲染頁面的過程 從耗時的角度,瀏覽器請求、加載、渲染一個頁面,時間花在下面五件事情上: DNS 查詢 TCP 連接 HTTP 請求即響應 服務器響...

    gougoujiang 評論0 收藏0
  • AMD CMD

    摘要:腳本的無阻塞加載代碼此處可以放源碼使得該文件變大,以便異步加載時看效果代碼同步加載輸出和在文檔完成解析后,觸發事件前執行。對動態嵌入的腳本使用來達到類似的效果。是否在允許的情況下異步執行該腳本。該屬性對于內聯腳本無作用即沒有屬性的腳本。 腳本的無阻塞加載 moduleA.js 代碼 console.log(Im A); /* 此處可以放jquery源碼 使得該文件變大,以便異步加載時看...

    王軍 評論0 收藏0
  • css、js阻塞

    摘要:例如,當解析器被腳本阻塞時,解析器雖然會停止構建,但仍會識別該腳本后面的資源,并進行預加載。也就是說,會阻塞頁面的渲染但是,并不會阻塞的解析。的加載不會阻塞頁面的渲染和資源的加載,一旦加載到就會立刻執行。 大家是不是會遇到這樣的一個問題,頁面加載速度過慢,瀏覽器老在轉圈圈,頁面部分內容需要花費較多的時間才能加載出來? 要明白上述問題,我們需要知道是什么在阻塞頁面的渲染? 1、瀏覽器如何...

    gxyz 評論0 收藏0

發表評論

0條評論

最新活動
閱讀需要支付1元查看
<