2015-09-05 37 views
9

我一直在爲我的一個項目的HEAD部分中使用的外部腳本添加defer屬性。我查詢了多個延期腳本標籤的執行順序。推遲在瀏覽器上的腳本和執行順序

下面是我的觀察,這將有助於我們理解我的查詢更好:

http://www.w3.org/TR/html5/scripting-1.html

defer屬性存在,那麼當頁面完成解析執行腳本

defer屬性確實有效。但是,我對執行順序持懷疑態度。它在FF和Chrome上看起來不同。

按我的項目簡介:

<script defer="defer" src="{SERVER_PATH}/deps.js?1441452359"></script> 
<script defer="defer" src="{SERVER_PATH}/script1.js?1440067073"></script> 
<script defer="defer" src="{SERVER_PATH}/script2.js?1441451916"></script> 

這裏,deps.js約爲120KB(gzip壓縮)的巨大的文件,而,script1-3是20-50kb(gzip壓縮)的常規尺寸的。

在Firefox,defer'ed腳本的執行並開始出現的順序,但在相同的順序沒有完成。因爲,除非前面的腳本完成執行,否則在Chrome上,下一個腳本的執行無法啓動。它看起來像Chrome是有道理的。

要測試的執行順序,我在每個腳本的第一行和最後一行已經插入的console.log,對於例如在deps.js

console.log("Execution Start: deps"); 
// minified deps script content. 
console.log("Execution End: deps"); 

下面Firefox上的控制檯輸出:

Execution Start: deps 
Execution Start: script1 
Execution Start: script2 
// Script Error as script1 needs deps to render completely. 
// Script Error as script2 needs deps to render completely. 
Execution End: deps 

下面控制檯輸出上鉻:

Execution Start: deps 
Execution End: deps 
Execution Start: script1 
Execution End: script1 
Execution Start: script2 
Execution End: script2 

然而,在FF的行爲並不總是如上所示。有時它確實像Chrome一樣工作。它看起來像一個只有Firefox的問題。或者,可能是因爲deps.js文件太沉重,需要時間來渲染。

能與延遲類似經驗的人幫助我嗎?如果需要其他信息,請告訴我。

PS:像其他的解決方案,在頁面的底部移動的腳本是不是我期待在這一刻。

+3

當您推遲文件時,它們被保證(如果在瀏覽器中正確實現)執行它們以便它們出現在元素上。我最喜歡的問題解釋:http://www.growingwiththeweb.com/2014/02/async-vs-defer-attributes.html –

+1

@NinoŠkopac我同意你的意見。他們應該按順序執行。但FF有時似乎表現不一樣,執行開始順序一樣,但執行結束順序不一樣。在Chrome上相同的實現工作正常。奇。 –

+0

你使用的是最新版本的FF嗎? –

回答

4

HTML5.0規範說的:

如果該元素具有src屬性,而元素有defer屬性,元素已被標記爲「解析器插入」,且元素沒有一個異步屬性

的元件必須被添加到當在文檔完成解析與創建該元件分析器的文檔相關聯的將執行腳本的列表的末尾。

的任務在任務隊列中的網絡任務源的地方,一旦取算法已完成必須設置元素的「準備將解析器執行的」標誌。解析器將處理執行腳本。

因此它確實表示它延遲腳本執行,直到解析相關的Document,它也表示它被推入列表中。所以列表的順序應該是腳本順序被解析插入。

不過,第二部分那種讓我擔心。它基本上說它只會被標記爲執行,直到網絡任務完成下載腳本。然後......「解析器將處理執行腳本」。

我在規範中找不到的是覆蓋文檔解析後腳本執行的情況。當它們「準備好解析器執行」時,它是否按照列表順序執行腳本?或者等到列表中的所有腳本「準備好解析器執行」然後執行它們。

規格(步驟15):http://www.w3.org/TR/html5/scripting-1.html#script-processing-src-prepare

+0

從這聽起來,它們是按順序執行的。如果它等待所有的下載或者不是可能只是被實現定義的,並且不等待,除非需要進行排序可能是更好的實現? –

+0

我同意這很可能是更好的實現。當我寫這個答案只是暗示可能不同的瀏覽器之間的行爲,因爲它們是如何執行的。儘管最有可能不是這種情況。 – MinusFour

0

我會說這是不是真的不可能的,除非「執行結束的」日誌中不同事件循環比「開始執行」日誌發生。

你能確定我們嗎?否則,這意味着Firefix會在這裏進行一些多線程處理,而且據我們所知,JS中沒有支持這一點。