2013-02-19 12 views
5

Istnieje kilka pytań, które pytają o buforowanie obiektów jQuery, ale nie mogę znaleźć takiego, które pyta, gdzie dokładnie obiekty jQuery mogą i powinny być buforowane. Mam stronę internetową, która ma pojedynczy plik JavaScript z wieloma funkcjami, jak pokazano poniżej.Na jakim poziomie należy buforować wyniki kwerend DOM jQuery?

$(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   
} 

W myFunctionOne I nieefektywnie zapytania DOM dwa razy, podczas gdy w myFunctionTwo kwerendy DOM raz, buforuje wynik w zmiennej lokalnej, a następnie pracować z tej zmiennej. Rozumiem, że podejście w myFunctionTwo jest bardziej wydajne, ale nie jestem pewien, gdzie faktycznie powinien być buforowanie tych obiektów. Z chwilą buforowania obiektu na poziomie metody, ale zastanawiam się, czy mogę faktycznie buforować go na wyższym poziomie, a następnie używać go w wielu funkcjach. W ten sposób zapytałbym DOM tylko raz, a następnie wykorzystałbym wynik we wszystkich funkcjach w tym pliku. Przykład tego, co sugeruję, pokazano poniżej.

$(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   
} 

Czy to podejście jest rozsądne, czy jest lepszy sposób na zrobienie tego? Być może używanie .ready jest złym miejscem do zrobienia tego rodzaju instalacji, ponieważ spowalnia to ładowanie strony? Czy istnieje alternatywny sposób buforowania obiektów jQuery na poziomie obiektu lub czy powinny one być buforowane tylko na poziomie funkcji?

Odpowiedz

7

Jak zawsze w tego rodzaju pytania, nie zoptymalizować przedwcześnie. W tym przypadku oznacza to, że nie używaj buforowania, dopóki nie zauważysz problemów z wydajnością. Jeśli Twoi klienci docelowi korzystają z komputerów o niskim poziomie specjalizacji lub urządzeń przenośnych, oznacza to, że sam chciałbyś przetestować na słabym sprzęcie, aby zidentyfikować takie problemy. Zdecydowanie zaleca się, aby przejść do przejrzystości przed próbą zwiększenia prędkości poprzez dodanie buforowania.

Niektóre dalsze punkty:

  • Jeśli używasz selektor, który używa identyfikatora należy szybko, jak będzie korzystał getElementById za kulisy, więc nie powinno być potrzeby buforowania.
  • Użyj metody łańcuchowania zamiast buforowania, które będzie używać selektora tylko raz.
  • Jeśli zaimplementujesz buforowanie, zrób to lokalnie jako pierwszy. Przechowywanie pomiędzy metodami będzie kosztować więcej w złożoności kodu niż lokalne buforowanie.
  • Używanie jest w porządku. Działa po załadowaniu DOM i jest właściwym miejscem do wykonywania zadań konfiguracyjnych.
+1

Zgadzam się z twoim punktem, że ważne jest, aby nie optymalizować go przedwcześnie, aw moim przypadku nie jest to przedwczesne.Widzę problemy z wydajnością w IE8 i próbując to naprawić, patrzymy na niektóre z zalecanych najlepszych praktyk dla jQuery, z których jednym jest buforowanie selektorów. Mam zamiar używać co najmniej buforowania lokalnego i buforowania między metodami, jeśli to możliwe. Powiedziałeś: "Przechowywanie pomiędzy metodami będzie kosztować więcej w złożoności kodu niż lokalne buforowanie". Czy możesz to wyjaśnić, ponieważ może to pomóc w odpowiedzi na moje oryginalne pytanie? – user2088756

1

Jednym ze sposobów może być przechowywanie wybierak w $.cache:

$(function(){ 

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

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

}); 

A potem do niego dostęp za pomocą:

function myFunctionOne() { 

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

To nie ma żadnych zalet w porównaniu do używania samej zmiennej (unikanie globalnej, jeśli jest to pożądane - i powinno być pożądane - z owijką IIFE). Ale ma złożoność i koszty wydajności w porównaniu do używania własnej zmiennej. –

-1

Ten kod będzie ładnie zaciemniać. Możesz dodać dowolną liczbę elementów sterujących w _initControls i używać ich później w całym bloku skryptu. Jeśli chcesz, aby był on globalny dla wszystkich bloków skryptu, przenieś funkcję _initControls z funkcji onreadystate jQuery.

$(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

Dlaczego ten post został odrzucony? – Ankur

Powiązane problemy