關於script標籤的 defer 屬性

談論到網站的載入速度,javascript的延遲載入似乎是很常被提到的課題。

事實上確實也是個舉足輕重的地方,所謂"延遲載入做得好,網頁速度沒煩惱!"

好啦!誇張了,進入主題吧!

網路上琳琅滿目的延遲載入方式,看得眼花撩亂,當然難免有些會讓人誤解的地方。

<script>標籤中的defer屬性就是個會讓人誤解的地方。

defer 英文是 延遲 的意思,不過這裡的延遲指的卻不是指載入的延遲,而是執行的延遲!

所以說給一個載入外部js檔的<script>標籤加上延遲屬性,並不會阻止js檔的載入,

而是會將執行的時間延遲到文檔完全解析完成與顯示後才開始執行,

理論上這js的執行時間應該先於DOMContentLoaded事件,

但實務上似乎與瀏覽器或是當時執行狀況有關。(我其實沒有驗證過這件事)

看一下HTML4.01的定義:

defer [CI]
When set, this boolean attribute provides a hint to the user agent that the script is not going to generate any document content (e.g., no "document.write" in javascript) and thus, the user agent can continue parsing and rendering.

整段話的意思是說:

當defer 屬性被設定時,這屬性的意義就是告訴UA ( 對大部分人而言,可以理解為瀏覽器 )

這段script不會產生任何文件內容 ( 像是不會在javascript中使用"document.write" ),

所以UA可以繼續下面文件的解析跟翻譯。

所以說defer屬性不能改善網頁速度?也不能這樣講,defer雖然不會延遲下載,不過它會延遲執行,

也可以同時下載多個js檔,這點對瀏覽器顯示畫面速度是有相當改善的。

(其實先在許多新的瀏覽器都支援平行下載)

但是還有一點值得注意,即便是有了defer屬性延遲執行,但這依然是在onload事件發生之前必須完成的。

意思就是說js檔的下載與執行會推延onload事件的發生時間。

通常這不會有什麼大問題,但是如果確實需要在onload事件的處理函式中實現一些重要功能時,

那被一些不太重要,或是與本文無關的js檔,像是廣告之類的擋到了onload事件,

也是件挺殺風景的事。

想要避免這狀況,把js檔的載入放在onload事件的處理函式中進行動態處理,不失為個好方法。

把javascript放到onload事件中處理的方法網路上有很多,這裡暫且不提。

但有還是要說一下,這種做法的缺點是,

開始下載js檔的時間是在onload之後,比起在本文內使用defer標籤的script要來的晚很多。

另外一點要注意的是,在HTML中的規範defer 應該是個布林值,

但是IE基本上不理會這一點,他只判斷是否有defer屬性,

所以就算是這樣寫 defer="false" IE一樣會把它當成有defer屬性來處理,

很明顯是個坑,不得不小心。

除此之外,還有一個坑,網路上還有許多文章會說defer在IE會有副作用,

有時候會只剩下某個有defer的script標籤中的內容。

其實主要的原因是,有defer屬性的script本來就是延遲執行的。

試想,如果在網頁顯示完後,你再來個document.writeln()..

那不就全部的網頁內容都被蓋過去了@@"

廣告也是一樣的,如果沒處理好該顯示的位置,那整個畫面就只剩廣告了。

smiley如果你覺得寫的還不錯,請給我一個讚喔!!smiley

 
 

  按個讚!~支持本站!~

FB推薦載入中  

你可能會有興趣的文章:

回到頂部