2012-01-19 4 views

Odpowiedz

6

Ponieważ $('#id').find('p') jest zoptymalizowany do zrobienia ...

document.getElementById('id').getElementsByTagName('p'); 

... natomiast Zgaduję $('#id p') będzie użyć querySelectorAll jeśli są dostępne, lub silnik wybierak oparty JavaScript czy nie.


Należy zauważyć, że wydajność zawsze ma odmiany między przeglądarkami. Opera znana jest z niezwykle szybkiego querySelectorAll.

Również różne wersje jQuery mogą proponować różne optymalizacje.

Może być tak, że $('#id p') będzie (lub obecnie jest) z tą samą optymalizacją, co pierwsza wersja.

+0

Zakładam, że 'querySelectorAll ('# id p')' jest całkiem zoptymalizowany. Różnice w wydajności powinny być testowane, a nie potwierdzane. – Tomalak

+1

@ Tomalak: Zrobiłem wystarczająco dużo testów 'qSA', aby wiedzieć, że w większości przeglądarek jest naprawdę bardzo powolny w porównaniu. To nie jest przypadkowe twierdzenie. Zobacz moją aktualizację dotyczącą * Opery *. –

+0

Nie powiedziałem, że qSA zawsze będzie szybsze. Powiedziałem * "Zakładam" * faktycznie, aby udowodnić moją rację. W końcu trudno jest obsługiwać tak uogólnioną instrukcję w taki czy inny sposób, biorąc pod uwagę szerokie różnice w wersjach jQuery i przeglądarkach. – Tomalak

2

Jest to specyficzne dla przeglądarki, ponieważ jQuery używa querySelectorAll, gdy jest dostępna. Kiedy testowałem w WebKit, było to naprawdę szybsze. Jak się okazuje, zoptymalizowano dla tego przypadku querySelectorAll.

Wewnątrz WebKit, jeśli cały selektor to #<id>, a dokument ma tylko jeden element o tym identyfikatorze, jest zoptymalizowany pod kątem getElementById. Ale jeśli selektorem jest cokolwiek innego, przetrząsa dokument szukając pasujących elementów.

Tak, powinno być możliwe zoptymalizowanie tej sprawy, aby działały tak samo - ale w tej chwili nikt jej nie ma. Możesz go znaleźć w źródle WebKit here, SelectorDataList::execute używa SelectorDataList::canUseIdLookup, aby zdecydować, czy użyć getElementById. Wygląda to tak:

if (m_selectors.size() != 1) 
    return false; 
if (m_selectors[0].selector->m_match != CSSSelector::Id) 
    return false; 
if (!rootNode->inDocument()) 
    return false; 
if (rootNode->document()->inQuirksMode()) 
    return false; 
if (rootNode->document()->containsMultipleElementsWithId(m_selectors[0].selector->value())) 
    return false; 
return true; 

Jeśli testowaliśmy w przeglądarce non-WebKit, to możliwe, że brakuje podobnych optymalizacje.