Best practice per migliorare le prestazioni
Indice
Questo capitolo tratta molte migliori pratiche JavaScript e jQuery, senza un particolare ordine.
Molte di queste pratiche si basano sulla presentazione jQuery Anti-Patterns for Performance (in inglese) di Paul irlandese.
Salva la lunghezza del loops
⤽
In un ciclo, è necessario accedere alla lunghezza di un array ogni volta che viene valutata la condizione; tale valore può essere memorizzato in anticipo in una variabile.
Aggiungere nuovi contenuti fuori da un ciclovar myLength = myArray.length; for (var i = 0; i < myLength; i++) { // fare delle cose }
⤽
Se si sta inserendo molti elementi nel DOM, fatelo tutti in una volta, non uno per volta.
Non Ripetersi// male $.each(myArray, function(i, item) { var newListItem = '<li>' + item + '</li>'; $('#ballers').append(newListItem); }); // meglio: fare questo var frag = document.createDocumentFragment(); $.each(myArray, function(i, item) { var newListItem = '<li>' + item + '</li>'; frag.appendChild(newListItem); }); $('#ballers')[0].appendChild(frag); // o questo var myHtml = ''; $.each(myArray, function(i, item) { html += '<li>' + item + '</li>'; }); $('#ballers').html(myHtml);
⤽
Nessuna ricorrenza; fare le cose una volta e solo una, altrimenti è sbagliato.
Attenzione alle funzioni anonime// MALE if ($eventfade.data('currently') != 'showing') { $eventfade.stop(); } if ($eventhover.data('currently') != 'showing') { $eventhover.stop(); } if ($spans.data('currently') != 'showing') { $spans.stop(); } // BENE var $elems = [$eventfade, $eventhover, $spans]; $.each($elems, function(i,elem) { if (elem.data('currently') != 'showing') { elem.stop(); } });
⤽
Non è consigliabile utilizzare abbondantemente le funzioni anonime. Queste sono difficili da eseguire in debug, per la manutenzione, il test e suo riutilizzo. Al suo posto, utilizzare un valore letterale per organizzare e nominare i suoi controllori e le funzioni di retrochiamata (callback).
Ottimizzazione dei selettori// MALE $(document).ready(function() { $('#magic').click(function(e) { $('#yayeffects').slideUp(function() { // ... }); }); $('#happiness').load(url + ' #unicorns', function() { // ... }); }); // MEGLIO var PI = { onReady : function() { $('#magic').click(PI.candyMtn); $('#happiness').load(PI.url + ' #unicorns', PI.unicornCb); }, candyMtn : function(e) { $('#yayeffects').slideUp(PI.slideCb); }, slideCb : function() { ... }, unicornCb : function() { ... } }; $(document).ready(PI.onReady);
⤽
L’ottimizzazione dei selettori è meno importante di una volta, grazie all’implementazione in alcuni browser web document.querySelectorAll(), passando il peso di jQuery verso browser web. Tuttavia, ci sono alcuni consigli da tenere a mente.
Selettori basati sugli ID
Utilizzare la delegazione di Eventi Selettori basati sugli ID
⤽
È sempre meglio iniziare le selezioni con un ID.
L’esempio che utilizza
Specificità// veloce $('#container div.robotarm'); // super-veloce $('#container').find('div.robotarm');
$.fn.find
è più veloce perché la prima selezione utilizza il motore di selezione interno Sizzle -. Mentre la selezione realizzata unicamente per ID utilizza document.getElementById()
, che è estremamente veloce grazie alla è una funzione nativa del browser web.⤽
Cercate di essere specifico per il lato destro della selezione e meno specifici per il sinistro.
Utilizzare il più possibile tag.classe del lato destro della selezione, e solo tag o .classe a sinistra.
La seconda selezione ha prestazioni migliori perché attraversa meno strati per individuare l’elemento.
Evitare il selettore universale // non ottimizzato $('div.data .gonzalez'); // ottimizzato $('.data td.gonzalez');
Evitare specificità eccessiva
$('.data table.attendees td.gonzalez'); // molto meglio: eliminare il mezzo, se possibile, $('.data td.gonzalez');
⤽
Selezioni dove si specifica implicita o esplicitamente una selezione universale che può essere molto lento.
$('.buttons > *'); // molto lento $('.buttons').children(); // molto meglio $('.gender :radio'); // selezione universale implicita $('.gender *:radio'); // stesa cosa, ma in modo esplicito $('.gender input:radio'); // molto meglio
⤽
La delega di eventi permette vincolare un gestore eventi a un elemento contenitore (per esempio, una lista non ordinata) in luogo di molteplici elementi contenuti (per esempio, gli elementi in una lista). jQuery rende rende questo lavoro facile attraverso $.fn.live e $.fn.delegate. Se possibile, si raccomanda utilizzare $.fn.delegate anziché $.fn.live, giacché elimina la necessità di una selezione e il suo contesto esplicito riduce il carico di circa il 80%.
Separare elementi per lavorare con loro Inoltre, la delegazione di eventi permette di aggiungere nuovi elementi contenitori alla pagina, senza dover vincolare i loro gestori di eventi.
// sbagliato (se ci sono molti elementi nella lista) $('li.trigger').click(handlerFn); // meglio: delegazione di eventi con $ fn.live. $('li.trigger').live('click', handlerFn); // molto meglio:. delegazione di evento con $ fn.delegate // permette specificare un contesto in modo facile $('#myList').delegate('li.trigger', 'click', handlerFn);
⤽
Se possibile, evitare la manipolazione del DOM. Per contribuire a questo scopo, dalla versione 1.4 jQuery introduce $.fn.detach il quale permette lavorare con gli elementi del DOM in forma separata per poi inserirli.
Utilizzare stili a cascata per modificare il Css tra vari elementivar $table = $('#myTable'); var $parent = $table.parent(); $table.detach(); // ... si aggiungono molte celle alla tabella $parent.append($table);
⤽
Se si modifica il CSS in più di 20 elementi con $.fn.css, considerate le modifiche agli stili con l’aggiunta di un tag style. Ciò consentirà di aumentare le prestazioni del 60%.
Utilizzare $.data anziché $.fn.data// corretto fino a 20 elementi, lento dopo i 20 elementi $('a.swedberg').css('color', '#asd123'); $('<style type="text/css">a.swedberg { color : #asd123 }</style>') .appendTo('head');
⤽
Utilizzare $.data in un elemento DOM invece di $.fn.data in una selezione può essere fino a 10 volte più veloce. Prima di farlo, assicuratevi di capire la differenza tra un elemento DOM e una selezione jQuery.
Non agire su elementi inesistenti // regolare $(elem).data(key,value); // 10 volte più veloce $.data(elem,key,value);
⤽
jQuery non ci dirà se si cerca di eseguire un codice su una selezione vuota – questo verrà eseguito come se nulla fosse. Dipende da noi vedere se la selezione contiene elementi.
Questo consiglio è particolarmente adatto per i widget jQuery UI, i quali hanno un carico pesante, anche quando la selezione non contiene elementi.
Definizione di variabili// SBAGLIATO: il codice esegue tre funzioni // senza verificare se ci sono // nella selezione $('#nosuchthing').slideUp(); // MEGLIO var $mySelection = $('#nosuchthing'); if ($mySelection.length) { $mySelection.slideUp(); } // MOLTO MEGLIO: aggiunge una estensione doOnce jQuery.fn.doOnce = function(func){ this.length && func.apply(this); return this; } $('li.cartitems').doOnce(function(){ // fare qualcosa });
⤽
Le variabili possono essere definite in una unica dichiarazione, invece di più volte.
Nelle funzioni di autoeseguibili, le definizioni di variabili possono essere passate tutte insieme.
Condizionali// antico var test = 1; var test2 = function() { ... }; var test3 = test2(test); // migliore modo var test = 1, test2 = function() { ... }, test3 = test2(test);
(function(foo, bar) { ... })(1, 2);
⤽
// antico if (type == 'foo' || type == 'bar') { ... } // migliore if (/^(foo|bar)$/.test(type)) { ... } // ricerca in oggetto letterale if (({ foo : 1, bar : 1 })[type]) { ... }
⤽
Utilizzare il codice sorgente della libreria come se fosse la sua documentazione – salva il link http://bit.ly/jqsource come marcatore per usarlo come riferimento.
Ancora nessun commento