2012-03-04 29 views
32

我以前問過similar question,但我從未明確表達過我的觀點,或者至少我認爲這是一個相關的問題,值得提出來看看是否有人可以提出一些有見地的想法。爲什麼jQuery.ready在如此慢的時候推薦?

當使用jQuery時,我們很多人使用jQuery.ready函數在DOM加載時執行init。它已經成爲使用jQuery將DOM操作程序添加到網頁的事實上的標準方式。存在相關事件natively某些瀏覽器,但jQuery在其他瀏覽器(如某些IE版本)中模擬它。例如:

<head> 
<script> 
    var init = function() { alert('hello world'); }; 
    $.ready(init); 
</script> 

現在,我們所有的測試都顯示這個事件可能會很慢。它並不像window.onload那麼慢,但它仍然通常在執行前大約100毫秒的延遲。如果FF可以高達200-300毫秒,尤其是刷新。

這些都是一些非常重要的毫秒,因爲這是在進行任何DOM操作(例如隱藏下拉列表)之前初始佈局顯示的時間量。很多時候,佈局「閃爍」主要是由於使用緩慢的DOM就緒事件造成的,迫使程序員使用CSS來隱藏元素,並可能使其不易訪問。

現在,如果我們不是放在一個腳本標記的初始化函數關閉標記之前,它將被更快執行,一般在半個月的時間,但有時甚至更快:

<head> 
<script> 
    var init = function() { alert('hello world'); }; 
</script> 
</head> 
<body> 
<!-- some HTML --> 
<script>init();</script> 
</body> 

一個簡單的測試頁面這證明了不同之處:http://jsbin.com/aqifon/10

我的意思是,我們並不是在談論使用有效的選擇器時,某些「優化警察」所倡導的幾乎不可察覺的差異。我們在討論一些在執行DOM操作onload時的主要延遲。在FF中嘗試這個例子,domready有時可能會慢100倍(300ms vs 2ms)。

現在對我的問題:爲什麼jQuery.ready建議使用時,它顯然比其他替代方案慢得多?在關閉BODY與使用jQuery.ready之前撥打init有什麼缺點?使用domReady可以說是更「安全」,但在什麼情況下比其他選擇更安全? (我正在考慮像document.write和延期腳本之類的東西)我們在許多客戶站點上使用了近3年的BODY方式,我們從未遇到過任何問題。它快了很多。

我也想知道,因爲jsPerf和優化選擇器每10000次執行幾毫秒有很多模糊之處,怎麼會沒有太多的這方面的討論呢?這基本上是用戶面臨的第一個延遲,並且在每個頁面加載時切片50-100毫秒似乎相當簡單...

回答

8

給點第一:

沒有,是在關閉之前<body>喊你init沒有缺點。它會像你已經注意到,依靠$.ready()更好地執行,並將完美地(甚至在IE)與所有的瀏覽器工作。

現在,有不過的理由使用$.ready(),而你的情況不適用大概:

  1. $.ready()很容易讓開發商做的東西以正確的順序。尤其重要的是不要引用尚未加載的DOM元素。雖然這很簡單,但很多開發人員仍然覺得很困惑。 $.ready()是一個不費腦筋的,儘管是一個緩慢的。
  2. 在你有幾個腳本需要init(),它不一定很容易/方便手動做你的身體的盡頭。它需要紀律和知道這些腳本的功能。特別是你會經常在依賴於jQuery的庫中看到$.ready(),因爲無論開發人員用什麼方式來加載庫,它都可以工作。
  3. 隨着異步模塊定義(例如require.js)成爲流行的加載您的JavaScript的方式,<body/>方法的結束不能保證。
6

一個優點是,您可以將代碼放置在頁面的任何位置。在我們的例子中,我們在我們的CMS中使用模板系統,將不同部分的大約10 - 30個模板(取決於複雜度)拼合在一起。

既然您希望模板可以在任何使用的頁面上工作,您需要在其中包含必要的Javascript。對於這些情況,ready()功能是真正的生活救星。

+3

是的,這個說法可以被貼上'方便'的標籤,這很公平。你可能可以在模板拼接結束時觸發jQuery.ready綁定,雖然... – David 2012-03-04 19:22:01

2

如果您已經編寫了其他人在其頁面中包含的JS文件,則在該文件中使用document.ready更安全(假設在DOM準備好後需要自動執行一些處理),因爲您可以'確定文件是否包含在頭部或身體的末尾。

當涉及到您完全控制的頁面時,顯然您沒有這種擔心,所以我沒有看到使用document.ready更安全,而不是調用您的init()身體的盡頭。使用document.ready(或onload)並將腳本放在主體的最後是兩種最常見的方法,而且它們很常見,因爲它們都運行良好。

您提到document.write()是一個可能的異常,但您不希望從document.ready或body的末尾調用它,因爲整個頁面都已被解析。

+0

只是要清楚:我不是在說文檔末尾放置腳本(如雅虎所宣傳的),我在說在關閉主體之前關於腳本的初始化(儘管如果您還將腳本放在文檔的末尾,則整個onload問題基本上沒有了)。 – David 2012-03-04 20:52:34

0

因爲它使domReady和window.load變慢。

對指標進行優化很容易,而不是實際的用戶體驗。所以即使交互延遲,「真正的用戶優化」圖表也會下降。