Javascript 的 async 跟 defer 有什麼不同
WriterShelf™ is a unique multiple pen name blogging and forum platform. Protect relationships and your privacy. Take your writing in new directions. ** Join WriterShelf**
WriterShelf™ is an open writing platform. The views, information and opinions in this article are those of the author.
Article info
Categories:
Tags:
Date:
Published: 2019/03/07 - Updated: 2021/04/16
Total: 960 words
Like
or Dislike
About the Author
很久以前就是個「寫程式的」,其實,什麼程式都不熟⋯⋯
就,這會一點點,那會一點點⋯⋯
More to explore
網站,少不了要用到外部的 Javascript,fontawesome、google analytics、adsense 等等,通常都有一大串,這外部的 Javascript 其實很容易拖累網頁的下載速度,所以,就有了以下三種寫法:
可是,這三種有什麼不同呢?簡單說:就是不同的擋不擋 HTML parsing 與 script 執行的時間點,這關係到您的網頁呈現的速度! 我在 google 的說明中,找到了以下這張圖,我覺得是最簡單易懂的。
Async 或 Defer? 來源:Loading Third-Party JavaScript
用文字簡單的說就是:有 Async 下載時,不會擋 HTML parsing,用 defer 則是都不擋 parsing,但是會在 HTML parsing 完後,才執行 script。
在 Rails 中怎麼寫?很簡單:
想要知道更深嗎?就請繼續看下去!
1、沒有 Async 也沒有 Defer
我們先來看看都沒加的情況,你可以在
<head>
</head>
間加入,或是加在<body>
</body>
間,這兩個有很大的差別:<head>
</head>
間:當瀏覽器看到這行 script 時,他就全部暫停執行網頁上的 HTML parsing 動作,等下載跟執行完後,才會再繼續網頁上的 HTML parsing,所以,這時 HTML parsing 還沒完!<body>
</body>
間:瀏覽器會做完所有的 HTML parsing 後,才下載跟執行這個 script,這也很慢,但是這時,HTML parsing 完了。2、Async 同步
這就是下載時,同時 HTML parsing 並沒有停止,只有執行時,會暫停 HTML parsing。Async 很像沒有寫 Async 在
<head>
</head>
間的 script,只是快多了,少了等待下載時間! 行為也像,這時 HTML parsing 還沒完 ! 要注意一點,因為是同步下載,所以沒人知道那一個 async 的 script 先執行,你如果有很多 script,執行的先後是不確定的。3、Defer 延緩
這跟 Async 一樣,下載時 HTML parsing 並沒有停止,但是,它會等到 HTML parsing 完了後,才執行,所以叫做「Defer 延緩」,這跟寫在
<body>
</body>
間沒有寫 Async/Defer 時的 script 行為很像,只是少了等待下載時間,快多了,執行時,HTML parsing 已經完了。 更細的說,當瀏覽器 HTML parsing 完後,發出 domInteractive event,Defer 的 script 開始執行,同時,image 跟其他的 CSS Assets 開始 render,都完了後,瀏覽器就會發出 domComplete event,在發出 onLoad。Async vs Defer
Async 跟 Defer 都只能用在
<head>
間,兩個都放,就會看瀏覽器版本了,很早的版本不認識 Async,它就會用 Defer,不過如上面說的,同時都用很沒有道理。在 HTML parsing 中,Async 會擋,defer 不會擋,這是很大的不同,
兩個都不能保證 HTML render 完成於否,你還是要自己用 onLoad 還是其他方法來確定,
誰最好?
我覺得 Async 跟 Defer 都好,要看用的地方,不過看起來,Defer 出問題的機率少一些,畢竟它是在 HTML parsing 完後,但是,都比不加好,快多了!
Turbolinks 5 使用者要注意
你如果用 Turbolinks 5,恭喜,又有一件事要注意了,turbolinks 5 因為會 cache head 間的 assets,所以,當然也會 cache 住 script,當 turbolinks 5 發現之前這個 script 已經存在 cache 裡面時,turbolinks 5 就不執行它了,這很重要,那怎麼辦,沒怎麼辦,就要多記一個例外,討厭的例外,如:
加上這 data-turbolinks-eval="false" 後,turbolinks 就不會去驗證 cache 了,我不喜歡這種用法,但是我還是在用 turbolinks,它... 已經挖了夠多的坑給我了。
希望對大家有幫助,講錯了請指正!
附上一些不錯的參考: