2013-02-19 31 views
5

有幾個問題需要緩存jQuery對象,但我找不到一個問題,究竟jQuery對象能夠並應該緩存在哪裏。我有一個網頁,其中包含一個JavaScript文件,其中包含一系列功能,如下所示。我應該在什麼級別緩存jQuery DOM查詢的結果?

$(document).ready(function() { 

    // do some setup 
}); 

/* function queries the DOM with the same selector multiple times without caching */ 
function myFunctionOne() { 

    $('#name_input').css("border","1px solid #ccc"); 
    $('#name_input').val(someValue);   
} 

/* function uses cached object from a single query */ 
function myFunctionTwo() { 

    var nameInput = $('#name_input') 
    nameInput.css("border","1px solid #ccc"); 
    nameInput.val(someValue); 
    // do some other stuff with cached selector   
} 

myFunctionOne我低效查詢DOM的兩倍,而在myFunctionTwo我查詢DOM一次,緩存結果在一個局部變量,然後用該變量的工作。我知道myFunctionTwo中的方法更高效,但我不確定應該在哪裏實際緩存這些對象。在那一刻,我在方法級緩存對象,但我想知道我是否實際上可以將它緩存在更高級別,然後在多個函數中使用它。這樣我只會查詢一次DOM,然後在該文件中的所有函數中重新使用結果。下面顯示了我所建議的一個例子。

$(document).ready(function() { 

    // do some setup 
    var nameInput = $('#name_input') 
}); 

/* function uses cached query result from .ready function above */ 
function myFunctionOne() { 

    nameInput .css("border","1px solid #ccc"); 
    nameInput .val(someValue);   
} 

/* function uses cached query result from .ready function above */ 
function myFunctionTwo() { 

    nameInput.val(someValue); 
    // do some other stuff with cached selector   
} 

這種方法是合理的還是有更好的方法呢?也許使用.ready函數是一個糟糕的地方做這種設置,因爲它會減慢頁面加載速度?有沒有其他的方法來緩存jQuery對象在對象級別或應該只緩存在功能級別?

回答

7

一如往常,在這類問題,不要過早優化。在這種情況下,它意味着在注意到性能問題之前不要使用任何緩存。如果您的目標客戶使用低規格電腦或移動設備,這意味着您需要自己測試低規格硬件,以便識別此類問題。我強烈建議您在嘗試通過添加緩存來提高速度之前清晰起見。

一些進一步指出:

  • 如果您使用的是使用一個ID的選擇,應該是快,因爲它會用getElementById在幕後,所以不應該需要緩存。
  • 使用方法鏈而不是緩存,它只會使用選擇器一次
  • 如果您確實實施緩存,請先在本地執行。方法之間的緩存比本地緩存的代碼複雜性成本更高。
  • 使用.ready是好的。它在DOM被加載後運行,並且是完成設置任務的完全正確的地方。
+1

我同意你的觀點,即不要過早優化它的重要性,在我的情況下,這是不成熟的。我在IE8中看到了性能問題,爲了糾正這個問題,我們正在尋找一些jQuery推薦的最佳實踐,其中之一就是緩存選擇器。我打算儘可能使用本地緩存並在兩種方法之間進行緩存。你說過,「方法之間的緩存代碼複雜性比本地緩存代價更大」。請你詳細說明一下,因爲這可能有助於回答我原來的問題嗎? – user2088756 2013-02-19 23:12:46

1

一種方法可能是選擇存儲在$.cache

$(function(){ 

     var $nameInput = $('#name_input'); 

     $('body').data({ nameInput: $nameInput }); 

}); 

,然後使用訪問:

function myFunctionOne() { 

    var $nameInput = $('body').data('nameInput'); 
} 
+0

與僅使用自己的變量(避免全局,如果需要的話 - 和它應該被期望 - 與包裝IIFE)相比,這沒有任何好處。但與使用自己的變量相比,它具有複雜性和性能成本。 – 2017-04-13 09:22:28

-1

此代碼將很好地混淆。您可以在_initControls中添加儘可能多的控件,並稍後在整個腳本塊中使用它們。如果你想全局到所有腳本塊,那麼將_initControls函數移出jQuery onreadystate函數。

$(function() { 
    "use strict"; 

    var _controls = {}, 
    _init = function() { 
     _initControls(); 
     _updateData("Hello"); 
    }, 
    _initControls = function() {    
     _controls.nameInput = $("#name_input"); 
    }, 
    _updateData = function (value) { 
     var nameInput = _controls.nameInput; 
     nameInput.css("border", "1px solid #ccc"); 
     nameInput.val(value); 
    }; 

    _init(); 
}); 
+0

爲什麼這篇文章被低估? – Ankur 2014-11-19 05:15:39

相關問題