2010-03-04 90 views
12

在做了一些關於這個主題的研究之後,我一直在嘗試很多模式來組織我的jQuery代碼(例如Rebecca Murphy在jQuery Conference上做了一個presentation的例子)。jQuery的代碼組織和性能

昨天我檢查了(揭示)模塊模式。結果看起來有點讓人想起YUI語法我想:

//global namespace MyNameSpace 
if(typeof MNS=="undefined"||!MNS){var MNS={};} 

//obfuscate module, just serving as a very simple example 
MNS.obfuscate = function(){ 
    //function to create an email address from obfuscated '@' 
    var email = function(){ 
     $('span.email').each(function(){ 
      var emailAddress = $(this).html().replace(' [ @ ] ','@'); 
      $(this).html('<a href="mailto:' + emailAddress + '">' + emailAddress + '</a>'); 

     }); 
    };  
    return { 
     email: email 
    };  
}(); 

//using the module when the dom's ready 
jQuery(document).ready(function($){ 
    MNS.obfuscate.email(); 
}); 

我到底有幾個模塊。一些自然包含的「私人成員」,在這種情況下意味着變量和/或函數,這些變量和/或函數對於本模塊中的其他函數僅僅是重要的,因此並沒有在返回語句中結束。

我認爲我的代碼連接的部分(與搜索示例有關的所有內容)組合在一個模塊中是有意義的,給出了整個事物結構。

但是寫這之後,我由約翰(Resig的),在那裏他還寫了關於模塊模式的性能讀取article

「實例化功能與一羣原型的屬性是非常,非常,如果你有一個你想讓人們進行交互的經常訪問的函數(返回一個對象),那麼有利於你擁有對象的屬性在原型鏈中並將其實例化,其代碼如下:

// Very fast 
function User(){} 
    User.prototype = { /* Lots of properties ... */ }; 

// Very slow 
function User(){ 
    return { /* Lots of properties */ }; 
} 

(約翰提到他並不反對模塊模式「本身」 - 只是爲了讓你知道:)

然後我不知道如果我正在用我的代碼進入正確的方向。事情是:我真的不需要任何私人成員,我也不認爲我暫時需要繼承。 我現在想要的只是一種可讀/可維護的模式。我想這可以歸結爲個人喜好,但我不想結束那些具有(相當嚴重的)性能問題的可讀代碼。

我不是JavaScript專家,因此就性能測試而言,更不是專家。首先,我不知道John提到的東西(「經常訪問的函數(返回對象),你希望人們與之交互的東西」,很多屬性等等)適用於我的代碼。我的代碼交互的文檔不是很大,有100或1000個元素。所以也許這根本不是問題。

但它來到我的腦海裏的一件事是,而不是僅僅有

$('span.email').each(function(){ 
    var emailAddress = $(this).html().replace(' [ @ ] ','@'); 
    $(this).html('<a href="mailto:' + emailAddress + '">' + emailAddress + '</a>'); 
}); 

(在domready中函數內部),我創建兩個「額外」的功能,模糊和電子郵件,由於使用的模塊模式。創建附加功能需要一段時間。問題是:在我的情況下它會是可衡量的嗎?

我不確定是否在上面的示例中創建了閉包(在jQuery論壇上的一篇有趣的文章中,我閱讀了以下內容:「有一個關於內部函數是否創建閉包的哲學爭論, t在外部函數的變量對象上引用任何東西......「),但是我確實在我的真實代碼中有閉包。儘管我不認爲我在那裏有任何循環引用,但我不知道這會導致內存消耗高/垃圾收集問題的程度如何。

我真的很想聽聽你的意見,也許看到你的代碼的一些例子。另外,您更喜歡哪些工具來獲取有關執行時間,內存和CPU使用率的信息?

回答

7

我也並不認爲我需要繼承暫且

確實。這並不適用於將模塊用作名稱空間。這是關於類實例類似物。

通過使用全新的{name: member}對象中的每個實例創建的對象效率都低於使用new ClassClass.prototype.name= member創建的對象的效率。在原型案例中,member值是共享的,導致重量較輕的實例。

在您的示例中,MNS是單身人士,因此通過原型共享成員沒有任何好處。

我不知道,如果在我的例子中創建上面

是封閉,它是。即使在外部函數中未定義變量,仍然會爲外部函數創建一個LexicalEnvironment和Scope對象,並綁定thisarguments。一個聰明的JS引擎可能能夠優化它,因爲每個內部函數都必須隱藏thisarguments以及它們自己的副本,但我不確定任何當前的JS實現是否真的這樣做。

在任何情況下,性能差異都應該無法檢測到,因爲您沒有在參數中加入任何重要內容。對於一個簡單的模塊模式,我不認爲有任何傷害。

此外,您更喜歡哪些工具獲取有關執行時間,內存和CPU使用率的信息?

開始的地方僅僅是在一個for循環執行代碼10000次,看看有多少大new Date().getTime()已經得到了,執行上儘可能多的不同的瀏覽器多次,你可以弄個。

$(this).html()。replace('[@]','@');

(這是應該做的?目前,它會讀取跨度的HTML到一個新的String,用@只更換的[ @ ]第一個實例,並返回一個新String值。它贏得了」 t更改DOM中的現有內容。)

+0

謝謝你的回答!我將不得不考慮一下它的主要部分,我想:) 至於電子郵件功能:你當然是對的。我只是想要一個簡單的例子,並將其複製到其中。我現在改變了,所以它會更有意義。 – north 2010-03-04 09:19:09

1

您有多少Javascript?根據我的經驗,在網頁上使用很多的Javascript代碼,性能問題一般來自代碼,實際上確實是的東西。一般來說,問題來自嘗試做太多事情,或試圖做一些特別的事情真的很糟糕。一個例子就是嘗試像表格行(大表)中的元素那樣執行類似綁定處理程序的事情,而不是使用「live」之類的東西。

我的觀點是,像你的模塊或功能或任何得到組織的東西幾乎肯定不會在你的網頁上造成任何類型的實際性能問題。什麼促使你去解決所有這些麻煩?

+0

感謝你,波蒂。我只是不滿意有一堆關於jQuery的準備就緒的函數。我想要一個讓閱讀和維護代碼更容易的模式,對於我自己和其他可能工作的人來說。我對JS編程有一定的瞭解,瞭解了jQuery/JS等一系列性能建議,但模式對性能影響有多大的問題要深入一些。所以John Resig的文章讓我很好奇。我想我是大多數開發人員:我想進步...... :) – north 2010-03-04 14:36:40

+0

是的,現在**,這使**很有意義。我在我的應用程序中做的是分離所有的JavaScript片段並對它們進行分類(jQuery擴展; blob在「ready」處理程序中運行;等等)。這使維護更容易。爲了將它們放在一起,我讓我的Ant構建運行Freemarker來組裝一個單一的Javascript源代碼,然後通過YUICompressor運行。 – Pointy 2010-03-04 14:42:04

+0

哦,到目前爲止,它並沒有那麼多:約250行,包括評論。模塊模式會產生一些開銷,但是即使沒有足夠的代碼,您也希望以某種方式組織它。我現在將它分成6個模塊,這使得它更具可讀性。所以在這方面,這種模式適合我。另外,在domready中調用像MNS.obfuscate.email這樣的命令,至少可以讓你知道發生了什麼。 – north 2010-03-04 14:45:07