2011-01-15 12 views
7

मैं दूसरे दिन सोच रहा था कि जब आप jQuery में चयनकर्ता टाइप करते हैं तो यह प्रदर्शन में एक अंतर डालता है यदि आप अपने चयनकर्ताओं को बहुत विशिष्ट या बहुत कम दिखाते हैं।jQuery अनुकूलन चयनकर्ता

जैसे

$('$myId .someElement') 

या

$('table#myId > tbody > tr > td > div.someElement'); 

2 विकल्प एक बहुत तेज है या अंतर neglectable होगा, कहते हैं कि जब .each() कर सकते हैं यदि आप पर एक ही तत्व खोजने की जरूरत है ।

उत्तर

4

मैं जाना होगा के लिए:

$('.someElement', '#myId') 

getElementById के बाद से सबसे तेजी से चयनकर्ता ऑपरेशन है, तो आपको पहले अपनी सामग्री फ़िल्टर कर रहे हैं और फिर वर्ग के लिए खोज। इसके अलावा चयनकर्ताओं को जितना तेज़ चयन होगा (निर्भर करता है कि वंशज या बच्चे चयनकर्ताओं - टिप्पणियों की जांच करें!)। @Test @ फ़ेलिक्स परीक्षण केस पर आधारित है।

संपादित करें: इसलिए इस उत्तर को बढ़ाने के लिए। jQuery documentation के आधार पर:

डिफ़ॉल्ट रूप से, चयनकर्ताओं दस्तावेज़ जड़ पर शुरू डोम के भीतर अपने खोजें कर। हालांकि, वैकल्पिक संदर्भ के लिए वैकल्पिक संदर्भ 0 $पैरामीटर $() फ़ंक्शन पर उपयोग करके खोज किया जा सकता है।

तो जब आप एक दूसरा पैरामीटर (एक संदर्भ) प्रदान करते हैं jQuery कि तत्व पहले और फिर इसे भीतर खोज के लिए खोज करेंगे, तो यह से अनुवाद किया जाएगा:

$('.someElement', '#myId') 

करने के लिए:

$('#myId').find('.someElement') 

अब चाल, अपने तत्व के निकटतम कंटेनर है कि वास्तव में एक आईडी रखती है खोजने के लिए और संदर्भ के रूप में यह डाल करने के लिए कोशिश कर रहा है, चूंकि आईडी चयन सबसे तेज़ है। अब आप कह सकते हैं कि क्यों तो दूसरी का उपयोग नहीं कर पहले से ही एक अनुवाद, द्वारा मैं वास्तव में परवाह नहीं है कि के बाद से पहली क्लीनर है ज्यादा है और यह काफी नहीं है धीमी:

    $('.someElement', '#myId')     $('#myId').find('.someElement') 
Chrome 8.0.552    36,527          37,400 
Firefox 3.6.13    17,632          19,155 
+0

इस परिणाम की उम्मीद नहीं थी, यह निश्चित रूप से सही जवाब है! धन्यवाद – Michael

+0

@ माइकल: आपका स्वागत है, और कृपया आपका प्रश्न सक्रिय होने पर उत्तर बटन को सीधे * टिक * न करें, खासकर जब @ फ़ेलिक्स भाग लेने वाले लोगों को ;-) – ifaour

+0

: डी मैं इसे तारीफ के रूप में लेता हूं :) बीटीडब्ल्यू। दिलचस्प परिणाम। मैंने सोचा कि '$ ('# myId .someElement') किसी भी मामले में तेज़ होगा, क्योंकि इसे सीधे 'querySelectorAll (' $ myId .someElement ')' में अनुवाद किया जा सकता है, लेकिन ऐसा लगता है कि' $ ('# myId')। ढूँढें ('कुछ एलीमेंट') 'बहुत तेज़ है। वाह। –

5

अद्यतन 2:

यहाँ कुछ अन्य टिप्पणी सारांश में। जवाब है यह पर निर्भर करता है।

jQuery का चयनकर्ता इंजन सिज़ल चयनकर्ता का मूल्यांकन करता है उसी तरह सीएसएस करता है: from right to left। तो आम तौर पर दाएं तरफ बहुत विशिष्ट और बाईं तरफ कम विशिष्ट होना बेहतर होता है।

लेकिन यह एचटीएमएल की संरचना पर निर्भर करता है और तत्वों को बिखरे हुए कैसे आप चाहते हैं।

तो अगर आप

      a 
         | 
         ... 
         | 
         b 
       ----------------- 
       |    | 
d d d c c c c c c c c c c c c c c c c c c c 

तो किया जा रहा है और अधिक विशिष्ट, तेजी से $('a b > c') है, क्योंकि आप तत्व b > c साथ जल्दी सेट कम कर रहे हैं और हर c के लिए a विरासत की जाँच करने की जरूरत नहीं है की है।

जबकि यदि आप,

      a 
         | 
         ... 
         | 
         b 
       ----------------- 
       |    | 
e e e e e e e e d d c c c c c c e e e e e e 

तो $('a c') तेजी से हो जाएगा के बाद से चयनकर्ता सरल है और b का एक बच्चा होने के लिए परीक्षण c इस मामले में अनावश्यक है (बेशक आप भी $('c') कर सकता है)।


मूल जवाब:

बावजूद जो उन में से एक, तेजी से होता है आप बार बार एक तत्व का उपयोग करने की है, दुकान इसे करने के लिए एक संदर्भ:

var $element = $('#myId .someElement'); 

$('some other selector').each(function() { 
    // access $element here 
}); 

The first selector seems to be a bit faster (क्रोम 8 में)।

नए ब्राउज़रों में (जो querySelectorAll का समर्थन करता है), अंतर शायद उन ब्राउज़र में जितना बड़ा नहीं है जो इसका समर्थन नहीं करते हैं।

अद्यतन:

मुझे लगता है कि यह ज्यादातर कितने निर्मित तरीकों jQuery का उपयोग कर सकते पर निर्भर करता है।तो यह सोचते हैं querySelector* उपलब्ध नहीं है, पहले चयनकर्ता दूसरे चयनकर्ता के लिए

document.getElementById('myId')[0].getElementsByClassName('someElement') 

में अनुवाद किया जा सकता है, jQuery अतिरिक्त जांच करने के लिए एक तत्व वास्तव में एक बच्चा है या नहीं होगा। अर्थात। कुछ और प्रसंस्करण शामिल है।

+0

ऐसा नहीं लगता कि यह प्रश्न का उत्तर है। – PeeHaa

+0

@PeeHaa: ठीक है, मैं इस प्रश्न में दो भागों को देखता हूं: 1) कौन सा चयनकर्ता तेज है? 2) इसे 'प्रत्येक' लूप में उपयोग करने के लिए। मेरा जवाब यह है कि इससे कोई फर्क नहीं पड़ता कि कौन सा तेज़ है क्योंकि आपको एक ही तत्व की बार-बार खोज नहीं करना चाहिए :) यह सवाल का सीधा जवाब नहीं हो सकता है लेकिन उम्मीद है कि वास्तविक समस्या के लिए एक अच्छा समाधान है। –

+0

+1, वास्तव में वह चांदनी नहीं है जिसे मैं ढूंढ रहा था लेकिन आप कोड ऑप्टिमाइज़ेशन में एक महत्वपूर्ण भूमिका निभाते हैं, वर्स में संग्रह करना बेहतर है और फिर लूप के अंदर कॉल करना बेहतर होता है। (मेरे लिए नया नहीं था;)) – Michael

-1

दूसरा एक तेज़ होगा, क्योंकि यह जानता है कि प्रत्येक चरण में वास्तव में क्या देखना है।

इस उदाहरण में:

$('table#myId > tbody > tr > td > div.someElement'); 

अगर कोई tbody, या कोई टीआर, या कोई टीडी (आदि) थे, यह खोज से बाहर शॉर्टकट सकता है सीधे। साथ ही, प्रत्येक अनुवर्ती चरण खोज को सीमित कर देगा (उदाहरण: <thead> के अंदर खोज नहीं)। इस उदाहरण से तुलना करें:

$('#myId .someElement') 

यह #myId के हर उप-तत्व को स्कैन करने के लिए होगा।


संपादित: FelixKing के रूप में बताया, अपना पहला उदाहरण $('#myId .someElement') वास्तव में तेजी है। केवल मामूली, लेकिन फिर भी, तेज़, इसलिए मैंने सोचा कि मुझे जवाब देना चाहिए। बच्चे चयनकर्ता (>) का उपयोग करके, वंशज चयनकर्ता (एक स्थान) के विपरीत सबसे तेज़ ट्रैवर्सल विधि है, क्योंकि तत्वों का संभावित सेट बहुत कम है। हालांकि, आधुनिक ब्राउज़रों ने अत्यधिक अंतर्निहित विधियों को अनुकूलित किया है जो jQuery कभी-कभी निष्पादन समय को कम करने के लिए उपयोग कर सकते हैं। इसलिए, जैसा कि इस विशेष मामले में देखा गया है, 'बदतर' वास्तव में बेहतर है, क्योंकि ब्राउज़रों को उस विशेष क्वेरी को निष्पादित करने के लिए बेहतर अनुकूलित किया जाता है। सामान्य रूप से, मूल बिंदु अभी भी खड़ा है, खासकर यदि आप ऐसा कुछ उपयोग कर रहे हैं जो संभावित रूप से ब्राउज़र द्वारा अनुकूलित नहीं किया जा सकता (उदाहरण के लिए कस्टम चयनकर्ता)।

+4

क्या आपके पास इसके लिए कोई बेंचमार्क परिणाम हैं या आप बस मानते हैं? क्योंकि मेरे परीक्षण कुछ अलग कहते हैं। –

+1

मैं पूरी तरह से @ फ़ेलिक्स से सहमत हूं! मुझे नहीं लगता कि दूसरा तेज है और वास्तव में परीक्षणों के परिणामस्वरूप यह नहीं है! ... मुझे लगता है कि (अगर गलत नहीं है) तो यह सीएसएस चयन (बाएं से दाएं) के समान दृष्टिकोण है? – ifaour

+0

जब यह तर्क नीचे आया तो मैंने एक ही निष्कर्ष निकाला, हालांकि @ ifaour का परीक्षण परिणाम कुछ अलग – Michael

0
'#myid .myclass' 

1) सभी तत्वों को खोजने जिसमें कक्षा myclass
2) प्रत्येक ऐसे तत्व के लिए, अपने पूर्वजों की श्रृंखला को ऊपर उठाएं और अगर आप #myid पूर्वजों के पास जाते हैं तो रोकें। यदि ऐसा कोई पूर्वज नहीं है, तो तत्व को त्यागें।

अब, यह बहुत अच्छी तरह से हो सकता है ब्राउज़रों इस प्रक्रिया का अनुकूलन है कि, उदाहरण के लिए:

1) #myid तत्व
2 लगता है) वर्ग myclass है और वह #myid तत्व के वंशज हैं कि सभी तत्वों को खोजने


table#myid > tbody > tr > td > div.mylcass 

नोट एक प्रकार चयनकर्ता के साथ आईडी चयनकर्ता लगाकर कोई प्रभाव नहीं है कि, के बाद से आईडी दस्तावेज़ में अद्वितीय हैं।

#myid > tbody > tr > td > div.mylcass 

एक प्रकार चयनकर्ता के साथ एक वर्ग चयनकर्ता उपसर्ग करना प्रदर्शन-वार बेहतर है। इसलिए, यदि आप तत्व के प्रकार को जानते हैं, तो आपको इसे सेट करने के लिए प्रोत्साहित किया जाता है।

मुझे उन बच्चों के चयनकर्ताओं के बारे में निश्चित नहीं है। मुझे लगता है कि यदि आप उनका उपयोग करते हैं तो यह तेज़ होना चाहिए। लेकिन कितनी तेजी से? संभवतः उपेक्षित? इसके अलावा, यह बदसूरत लग रहा है।

इस पर विचार करें:

#myid td > div.myclass 

तो #myid एक मेज तत्व है, और आप कोई नेस्टेड तालिकाओं, तो इस चयनकर्ता अपने दूसरे चयनकर्ता के रूप में के रूप में तेजी से होना चाहिए। मैं इसका इस्तेमाल करूंगा।

+0

सीएसएस चयन इस तरह से काम करते हैं (दाएं से बाएं), लेकिन मुझे नहीं लगता कि jQuery करता है। – nickf

+0

@nickf लेकिन jQuery 'querySelectorAll()' का उपयोग करता है, है ना? –

+0

@ ime - हाँ * कभी-कभी *। यदि क्वेरी कुछ ऐसी क्वेरी नहीं है, तो चयनकर्ता सभी संभाल नहीं सकता है, और यदि ब्राउज़र में वह फ़ंक्शन नहीं है। इस मामले में, हाँ यह होगा, लेकिन सामान्य रूप से, नहीं। – nickf

संबंधित मुद्दे