Ca vorbitori de limba engleză, mintea noastră este orientată spre interpretarea datelor și a textului de la stânga la dreapta. Cu toate acestea, după cum se dovedește, multe dintre motoarele de selecție JavaScript moderne (jQuery, YUI 3, NWMatcher) și nativ querySelectorAll
, parsează șirurile de selecție de la dreapta la stânga.
Este important să rețineți că, de cele mai multe ori, nu trebuie să vă faceți griji cu privire la performanța selectorului prea mult - atâta timp cât selectorii dvs. nu sunt obnoși. Sizzle-ul lui JQuery este incredibil de rapid și plăcut.
Luați în considerare următorul selector:
$ (caseta p ');
Deși unii - în general mai în vârstă - motoarele selective vor interoga mai întâi elementul DOM cu elementul a clasă
de cutie
, și apoi continuați să găsiți orice p
etichete care sunt copii, jQuery funcționează în sens invers. Începe prin interogarea DOM pentru toate paragrafele de pe pagină și apoi o execută până la nodurile părinte și căutări .cutie
.
Putem folosi site-ul excelent JsPerf.com pentru a testa acest lucru.
// Marcarea// Testul // 1. $ ('# caseta p'); // 2. $ ('# box') găsiți ('p');Salut
Imaginea de mai sus arată că utilizarea găsi()
sau (copii)
este de aproximativ 20-30% mai rapid, în funcție de browser.
Biblioteca jQuery are o optimizare care va determina imediat dacă o id
a fost trecut la obiectul jQuery ( $ ( '# Caseta')
). În acest caz, nu este necesar să utilizați Sizzle; în schimb, trece rapid selectorul la getElementById
. Și, bineînțeles, dacă browserul este suficient de modern, querySelectorAll
va prelua Sizzle.
Pe de altă parte, cu $ ('# box p')
, jQuery trebuie să parseze acest șir cu API-ul Sizzle, care va dura un pic mai mult (deși Sizzle are o optimizare pentru selectori care încep cu un id
). Acesta este motivul pentru care este, de asemenea, mai rapid să facem lucruri de genul $ (“. Elems'). Primul ()
peste $ ( 'Elems:. Primele')
. Ultimul selector va trebui să fie analizat.
Să examinăm un alt exemplu:
$ ("# container>: dezactivat");
Acest selector pare potrivit. Găsiți toate intrările dezactivate (sau, de fapt, elementele) care sunt în interiorul #container
. Cu toate acestea, așa cum am învățat, jQuery și nativul querySelectorAll
lucrează din dreapta în stânga. Aceasta înseamnă că jQuery va apuca literalmente orice element din DOM și va determina dacă este invalid
atributul este setat la true. Observați că nu există nicio filtrare prealabilă pentru a găsi în prealabil toate intrările de pe pagină. În schimb, fiecare element din DOM va fi interogat.
// De la jQuery Source disabled: function (elem) return elem.disabled === true;
Odată ce a fost compilată o colecție, ea călătorește apoi lanțul spre părinte și stabilește dacă este #container
. Desigur, acest lucru nu este eficient și, deși este adevărat că poate că prea multă atenție în comunitate este plătită performanței selectorului, trebuie să ne străduim să nu scriem selectori prea intensi, atunci când este posibil.
Puteți îmbunătăți acest selector un pic făcând:
// $ $ $ ("# container> input: disabled");
Acest cod va limita interogarea la toate intrările de pe prima pagină (mai degrabă decât fiecare element). Chiar și mai bine, totuși, putem folosi din nou găsi
sau copii
metodă.
$ ( '# Container') pentru copii ( 'intrare: dezactivat');.
Este important să reiterez faptul că, sincer, nu trebuie să vă faceți griji cu privire la performanța selectorului prea mult. Există o mulțime de optimizări în jQuery care vă vor ajuta. Este, în general, mai bine să vă concentrați pe elemente de bilete mai mari, cum ar fi organizarea și structura codurilor.
De exemplu, dacă Sizzle întâlnește un selector de genul $ ('# box p')
, este adevărat că funcționează de la dreapta la stânga, dar există și o optimizare rapidă a reglării, care va determina mai întâi dacă prima secțiune a selectorului este o id
. Dacă da, o va folosi ca context, atunci când caută etichetele paragrafului.
Cu toate acestea, este întotdeauna util să știți ce se întâmplă în spatele scenei - cel puțin la un nivel foarte scăzut.