link - javascript w3c中文




腳本標記-異步&延遲 (5)

我有一些關於<script>標籤asyncdefer的問題,這是我理解的,只能在HTML5瀏覽器中使用。

我的一個網站有兩個外部JavaScript文件,它們當前位於</body>標籤上方; 第一個是jquery源自谷歌,第二個是本地外部腳本。

尊重網站加載速度

  1. 向我在頁面底部的兩個腳本添加async是否有優勢?

  2. 將這兩個腳本的async選項添加到<head>的頁面頂部會有什麼好處嗎?

  3. 這是否意味著他們在頁面加載時下載?
  4. 我認為這會導致HTML4瀏覽器延遲,但會加速HTML5瀏覽器的頁面加載嗎?

使用<script defer src=...

  1. 使用該屬性將<head>的兩個腳本加載到與</body>之前的腳本相同的影響是否會defer
  2. 我再次假設這會讓HTML4瀏覽器變慢。

使用<script async src=...

如果我有兩個啟用了async腳本

  1. 他們會同時下載嗎?
  2. 或者與頁面的其餘部分一次一個?
  3. 腳本的順序是否會成為問題? 例如,一個腳本依賴於另一個,所以如果下載速度更快,則第二個腳本可能無法正確執行。

最後,我最好是讓事情保持原樣,直到HTML5更常用?


HTML5: asyncdefer

在HTML5中,您可以告訴瀏覽器何時運行您的JavaScript代碼。 有三種可能性:

<script       src="myscript.js"></script>

<script async src="myscript.js"></script>

<script defer src="myscript.js"></script>
  1. 如果沒有asyncdefer ,瀏覽器會在渲染腳本標記下方的元素之前立即運行腳本。

  2. 使用async (異步),瀏覽器將繼續加載HTML頁面並在瀏覽器同時加載和執行腳本時進行呈現。

  3. 隨著defer ,瀏覽器將在頁面完成解析時運行腳本。 (沒必要完成下載所有圖像文件,這很好。)


async和defer將在HTML解析期間下載文件。 異步會暫停HTML解析器。 它將在完成下載後執行。 在延期不會暫停HTML解析器的情況下,它將在解析器完成後執行。推遲執行將按照文檔中的順序執行。

當腳本不依賴任何東西時使用。 當腳本依賴使用。

最好的解決方案是將其添加到body的底部。阻止或渲染不會有問題。


</body>之前保留你的腳本。 異步可以在幾種情況下與位於那裡的腳本一起使用(參見下面的討論)。 對於那些位於那裡的腳本,延遲不會有太大的區別,因為DOM解析工作已經完成了。

這裡有一篇文章解釋了異步和延遲之間的區別: http://peter.sh/experiments/asynchronous-and-deferred-javascript-execution-explained/ : http://peter.sh/experiments/asynchronous-and-deferred-javascript-execution-explained/

如果您將腳本保留在</body>之前,那麼您的HTML將在舊版瀏覽器中更快地顯示。 因此,為了保持舊版瀏覽器的加載速度,您不希望將它們放在其他地方。

如果你的第二個腳本依賴於第一個腳本(例如你的第二個腳本使用第一個腳本中加載的jQuery),那麼你不能讓它們異步,沒有額外的代碼來控制執行順序,但是你可以讓它們延遲,因為延遲腳本會仍然按順序執行,直到文檔解析完成。 如果您擁有該代碼,並且不需要腳本立即運行,則可以使它們異步或延遲。

您可以將這些腳本放在<head>標記中,並將它們設置為defer並且將延遲腳本的加載,直到DOM被解析,並且在支持延遲的新瀏覽器中顯示快速頁面,但不會在所有瀏覽器中都可以幫助你,而且它並不比只在</body>之前放置腳本更快。 所以,你可以看到為什麼最好把它們放在</body>之前。

異步更有用,當你真的不在乎腳本何時加載,並且沒有任何依賴於用戶的東西取決於腳本加載。 最經常引用的使用異步的例子是像Google Analytics這樣的分析腳本,您不需要等待任何內容,即時運行並不是緊急事件,它是獨立的,因此沒有其他依賴它。

通常jQuery庫不適合async,因為其他腳本依賴於它,並且您希望安裝事件處理程序,以便您的頁面可以開始響應用戶事件,並且您可能需要運行一些基於jQuery的初始化代碼來建立初始狀態的頁面。 它可以用於異步,但其他腳本必須編碼,直到加載jQuery才能執行。


看起來延遲和異步的行為依賴於瀏覽器,至少在執行階段。 注意,延遲僅適用於外部腳本。 我假設異步遵循相同的模式。

在IE 11及以下版本中,順序似乎是這樣的:

  • 異步(可以在頁面加載時部分執行)
  • 無(可以在頁面加載時執行)
  • 延遲(在加載頁面後執行,所有延遲都按文件中的放置順序)

在Edge,Webkit等中,異步屬性似乎被忽略或放在最後:

  • data-pagespeed-no-defer(在加載頁面時在任何其他腳本之前執行)
  • 無(可以在頁面加載時執行)
  • 延遲(等到DOM加載,所有延遲都按文件中的放置順序)
  • 異步(似乎等到DOM加載)

在較新的瀏覽器中,data-pagespeed-no-defer屬性在任何其他外部腳本之前運行。 這適用於不依賴於DOM的腳本。

注意:如果需要明確執行外部腳本的順序,請使用延遲。 這告訴瀏覽器按照文件中的位置順序執行所有延遲的腳本。

ASIDE:加載時外部JavaScript的大小確實很重要,但對執行順序沒有影響。

如果您擔心腳本的性能,可能需要考慮縮小或僅使用XMLHttpRequest動態加載它們。


面對同樣的問題,現在清楚地了解兩者如何工作。希望這個參考鏈接將有所幫助...

異步

將腳本標記添加到腳本標記時,會發生以下情況。

<script src="myfile1.js" async></script>
<script src="myfile2.js" async></script>
  1. 進行並行請求以獲取文件。
  2. 繼續解析文檔,就好像它從未中斷過一樣。
  3. 下載文件時執行單個腳本。

推遲

Defer與一個主要不同之處在於異步非常相似。 以下是瀏覽器遇到具有defer屬性的腳本時發生的情況。

<script src="myfile1.js" defer></script>
<script src="myfile2.js" defer></script>
  1. 進行並行請求以獲取單個文件。
  2. 繼續解析文檔,就好像它從未中斷過一樣。
  3. 即使腳本文件已經下載完成解析文檔。
  4. 按照它們在文檔中遇到的順序執行每個腳本。

參考: 異步和延遲之間的區別





html5