Sosirea lui jQuery a făcut ca procesul de scriere a JavaScript să fie râzător de ușor. Dar, veți observa că modificarea ușoară a codului dvs. îmbunătățește semnificativ lizibilitatea și / sau performanța. Iată câteva sfaturi pentru a vă ajuta să vă optimizați codul.
Avem nevoie de o platformă solidă pentru a efectua testele noastre. Aici este marcajul HTML pentru pagina de testare în care vom rula toate testele noastre:
Testarea îmbunătățirilor de performanță - Siddharth / NetTuts+ Un text aici
- Bună ziua!
Nu este nimic special aici; doar o grămadă de elemente pe care le putem viza și testa. Folosim Firebug pentru a înregistra orele aici. profil începe procesul, și profileEnd o oprește și notează cât timp a fost făcută. În mod obișnuit, folosesc metoda principală a profilului Firebug, dar pentru scopurile noastre înșelătoare, acest lucru va fi suficient.
Așa cum se întâmplă adesea, veți difuza un singur fișier de script care conține codul dvs. la toate paginile site-ului dvs. Acesta este de obicei un cod care deseori efectuează acțiuni pe elementele inexistente din pagina curentă. Deși jQuery se ocupă de probleme cum ar fi acestea destul de grațios, acest lucru nu înseamnă că puteți ignora orice problemă. De fapt, dacă apelați metodele lui jQuery pe o colecție goală, acestea nu vor fi executate.
Ca o bună practică, trebuie doar să rulați codul care se aplică paginii încărcate în prezent, în loc să strângeți întregul cod într-un singur control al unui document și să-l difuzați clientului.
Să ne uităm la primul scenariu:
console.profile (); var ele = $ ("# cevaThatisNotHere"); ele.text ("Un text") slideUp (300) .addClass ("editare"); $ ( "# MainItem"); console.profileEnd (); // Unele coduri mai minunate și mai ruinate aici..
Firebug scuipă următorul rezultat:
De data aceasta, hai să verificăm dacă există elementul pe care căutăm să îl efectuăm înainte de a face acest lucru.
console.profile (); var ele = $ ("# cevaThatisNotHere"); dacă ele [0]) ele.text ("Un text") slideUp (300) .addClass ("editare"); $ ("# mainItem"); console.profileEnd (); // Unele coduri mai minunate și mai ruinate aici..
Și rezultatele:
Vedea? Este destul de simplu, până la capăt și face treaba. Rețineți că nu este necesar să verificați dacă există un element pentru fiecare bit al codului dvs.. Veți observa în pagina dvs. că anumite părți mai mari vor beneficia în general de această metodă. Folosește-ți judecata aici.
Încercați să utilizați un cod în loc să treceți o clasă.
Acesta este un subiect important, așa că o voi păstra cât mai concisă. În primul rând, când treceți în selectori, încercați să utilizați un cod de identitate în locul unei clase. jQuery folosește direct nativul getElementById metodă pentru a găsi un element prin ID, în timp ce în cazul unei clase trebuie să facă voodoo intern pentru a-l achiziționa, cel puțin în browserele mai vechi.
Vom analiza diferiții selectori pe care îi puteți folosi pentru a viza a doua Li element. Vom testa fiecare dintre ele și modul în care acestea modifică performanța.
Prima metodă, cea mai ușoară, va fi aceea de a viza în mod clar utilizarea acesteia selectat clasă. Să vedem ce se întoarce profibrul lui Firebug.
console.profile (); $ ( "Selectat."); console.profileEnd ();
Și rezultatul: 0.308ms. Apoi, prefixăm un nume de etichetă pentru al restrânge. În acest fel, putem să ne restrângem căutarea, vizând mai întâi numai elementele DOM selectate, cu document.getElementsByTagName.
console.profile (); $ ( "Li.selected"); console.profileEnd ();
Și rezultatul: 0.291ms. Aproape 0,02 ms ras. Acest lucru este neglijabil datorită faptului că testează în Firefox; cu toate acestea, trebuie remarcat faptul că această creștere a performanțelor va fi în mod considerabil mai mare în browserele mai vechi, cum ar fi Internet Explorer 6.
Apoi, coborâm din ID-ul elementului părinte.
console.profile (); $ ("# someList .selected"); console.profileEnd ();
Și rezultatul: 0.283ms. Să încercăm să fim puțin mai specifici. De asemenea, specificăm tipul de element în plus față de ID-ul strămoșilor.
console.profile (); $ ("# someListLi.selected"); console.profileEnd ();
Și rezultatul: 0.275 ms. O altă parte mică sa ras. În final, hai să-l direcționăm direct folosind un ID.
console.profile (); $ ( "# MainItem"); console.profileEnd ();
Și rezultatul: 0.165ms. Impresionant! Acest lucru vă arată cu adevărat cât de rapid este să executați metode native. Rețineți că în timp ce browserele moderne pot profita de lucruri precum getElementsByClassName, browserele mai vechi nu pot - ducând la performanțe mult mai lent. Luați întotdeauna în considerare acest lucru atunci când codificați.
Sizzle, motorul selector pe care jQuery îl folosește - construit de John Resig - analizează selectorii de la dreapta la stânga, ceea ce ridică câteva lanțuri neașteptate de analiză.
Luați în considerare acest selector:
$ ("# someList .selected");
Atunci când Sizzle întâlnește un astfel de selector, acesta construiește mai întâi structura DOM, folosind selectorul ca rădăcină, aruncă obiecte care nu au clasa necesară și, pentru fiecare element din clasă, verifică dacă părintele său are un ID de someList.
Pentru a ține cont de acest lucru, asigurați-vă că cea mai mare parte a selectorului dvs. este cât se poate de specifică. De exemplu, specificând li.selected in loc de .selectat, reduceți numărul de noduri pe care trebuie să le verificați. Acesta este motivul pentru care performanța a sărit în secțiunea anterioară. Prin adăugarea unor constrângeri suplimentare, reduceți efectiv numărul de noduri pe care trebuie să le verifice.
Pentru a obține o mai bună ajustare a modului de obținere a elementelor, trebuie să consultați adăugarea unui context pentru fiecare solicitare.
var someList = $ ('# someList') [0]; $ ("selectat", someList);
Prin adăugarea unui context, modul în care elementul este căutat se modifică complet. Acum, elementul care furnizează contextul - someList în cazul nostru - este căutat mai întâi și, odată obținută, elementele copil care nu au clasa necesară sunt eliminate.
Rețineți că, în general, este o practică bună să transmiteți un element DOM ca și context al selectorului jQuery. Folosirea unui context este foarte util atunci când este stocată în unele variabile. În caz contrar, puteți simplifica procesul și utiliza find () - care jQuery, în sine, face sub capota.
$ ( '# SomeList') găsește ( 'selectat.').;
Aș vrea să spun că creșterea performanței va fi clar definită, dar nu pot. Am executat teste pe un număr de browsere și dacă performanța abordării scoped bate ca cea a versiunii vanilie depinde de o serie de factori, inclusiv dacă browserul acceptă metode specifice.
Când navigați prin codul altcuiva, veți găsi adesea.
// Alte coduri $ (element) .doSomething (); // Mai mult cod $ (element) .doSomethingElse (); // Chiar mai mult cod $ (element) .doMoreofSomethingElse ();
Nu faceți asta. Vreodată. Dezvoltatorul este instantierea acestui "element" de peste si peste. Acest lucru este risipitor.
Să vedem cât de mult timp are nevoie un astfel de cod oribil pentru a alerga.
console.profile (); $ ( "# MainItem") ascunde ().; $ ( "# MainItem") val ( "Bună ziua").; $ ("# mainItem"). html ("Oh, hey there!"); $ ( "# MainItem") arată ().; console.profileEnd ();
Dacă codul este structurat ca mai sus, unul după altul, puteți utiliza înlănțuirea astfel:
console.profile (); $ ("# mainItem") hide () val ("Hello") html ("Oh, hey there! console.profileEnd ();
Prin înlănțuire, elementul inițial trecut este dobândit și o referință este transmisă de-a lungul fiecărei apeluri ulterioare, tăind timpul de execuție. Altfel, un nou obiect jQuery este creat de fiecare dată.
Dar dacă, spre deosebire de cele de mai sus, secțiunile care fac referire la element nu sunt concurente, va trebui să cacheți elementul și apoi să faceți toate aceleași operații ca înainte.
console.profile (); var elem = $ ("# mainItem"); elem.hide (); // Unele cod elem.val ("Hello"); // Mai multe cod elem.html ("Oh, hey there!"); // Chiar mai mult codul elem.show (); console.profileEnd ();
După cum reiese din rezultate, memorarea în cache sau înlănțuirea scade considerabil timpul de execuție.
Sugerând manipularea DOM non-tradițională în articolul meu anterior, a atras un mic pic de la câțiva oameni înainte de a fi arătat că creșterea performanței merită într-adevăr. Acum o vom testa.
Pentru test, vom crea 50 Li elemente și adăugați-le în lista curentă și stabiliți cât timp este nevoie.
Vom revizui mai întâi metoda normală, ineficientă. În mod esențial, adăugăm elementul la listă de fiecare dată când se execută buclă.
console.profile (); var lista = $ ("# someList"); pentru (var i = 0; i<50; i++) list.append('
Să vedem cum a făcut-o, nu-i așa??
Acum, vom urma o cale ușor diferită. Vom adăuga, în esență, șirul HTML necesar pentru o variabilă de fir și apoi vom reîmprospăta DOM-ul o singură dată.
console.profile (); var lista = $ ("# someList"); var items = ""; pentru (var i = 0; i<50; i++) items += '
După cum era de așteptat, timpul necesar a scăzut semnificativ.
Dacă utilizați jQuery ca înlocuitor pentru getElementById, dar nu utilizați niciodată una dintre metodele sale furnizate, atunci faceți acest lucru greșit.
Dacă doriți să faceți mai multe lucruri, întrebați-vă dacă într-adevăr trebuie să creați un nou obiect jQuery, toate în scopul direcționării unui element? Dacă utilizați jQuery ca înlocuitor pentru document.getElementById, dar nu utilizați niciodată metodele furnizate, atunci faceți greșit. În acest caz, putem să scăpăm de JS brut.
console.profile (); var lista = document.getElementById ('someList'); var var = =; pentru (var i = 0; i<50; i++) items += '
Veți observa că diferența dintre timpul de execuție dintre codul optimizat și cel optimizat este în fracțiunea de interval de milisecunde. Acest lucru se datorează faptului că documentul nostru de testare este foarte mic, cu un număr imposibil de mici de noduri. Odată ce începeți să lucrați cu site-uri de nivel de producție cu câteva mii de noduri în el, se va adăuga cu adevărat.
De asemenea, rețineți că, în majoritatea acestor teste, accesez simplu elementele. Când începeți să le aplicați funcții adecvate, delta în timpul de execuție va crește.
De asemenea, înțeleg că nu este vorba despre cele mai științifice metode de testare a performanței, însă, pentru a obține o simțire generală a modului în care fiecare dintre aceste modificări afectează performanța, cred că acest lucru este suficient de adecvat.
În cele din urmă, în majoritatea aplicațiilor web, viteza de conectare și timpul de răspuns al serverului web în cauză vor juca un rol mai mare în performanța aplicației dvs. mai mult decât trucurile din codul pe care îl veți realiza. Cu toate acestea, aceasta este în continuare informații importante și te va ajuta să coborâți linia atunci când încerci să scoți cât mai multă performanță din codul tău.
Și am terminat. Câteva puncte pe care să le țineți minte când încercați să vă optimizați codul; aceasta nu este lista cuprinzătoare a trucurilor, desigur, iar punctele nu se aplică neapărat în toate situațiile. Oricum, o să urmăresc comentariile îndeaproape pentru a citi ceea ce trebuie să spui pe această temă. Orice greseala pe care o vezi aici? Dați-mi o linie mai jos.
Întrebări? Ce lucruri frumoase de spus? Critici? Activați secțiunea de comentarii și lasă-mă un comentariu. Codificare fericită!