سؤال

أنا أبحث عن أي طريقة يمكنني من خلالها تحسين أداء المحدد لمكالمة jQuery.على وجه التحديد أشياء مثل هذا:

يكون $("div.myclass") اسرع من $(".myclass")

أعتقد أنه قد يكون كذلك، لكنني لا أعرف ما إذا كان jQuery ذكيًا بما يكفي لتقييد البحث حسب اسم العلامة أولاً، وما إلى ذلك.هل لدى أي شخص أي أفكار حول كيفية صياغة سلسلة محدد jQuery للحصول على أفضل أداء؟

هل كانت مفيدة؟

المحلول

ليس هناك شك في ذلك تعد التصفية حسب اسم العلامة أولاً أسرع بكثير من التصفية حسب اسم الفئة.

سيكون هذا هو الحال حتى تنفذ كافة المتصفحات getElementsByClassName أصلاً، كما هو الحال مع getElementsByTagName.

نصائح أخرى

في بعض الحالات، يمكنك تسريع الاستعلام عن طريق تحديد سياقه.إذا كان لديك مرجع عنصر، فيمكنك تمريره كوسيطة ثانية لتحديد نطاق الاستعلام:

$(".myclass", a_DOM_element);

ينبغي أن يكون أسرع من

$(".myclass");

إذا كان لديك بالفعل عنصر_DOM_element وهو أصغر بكثير من المستند بأكمله.

كما ذكر ريد أعلاه، تعمل jQuery من الأسفل إلى الأعلى.بالرغم من

هذا يعني $('#foo bar div') أبطأ بكثير من $('bar div #foo')

هذا ليس المقصود.إذا كان لديك #foo لن تضع أي شيء قبله في المحدد على أي حال نظرًا لأن المعرفات يجب أن تكون فريدة.

المقصود هو:

  • إذا كنت تقوم بتحديد أي شيء فرعيًا من عنصر بمعرف، فحدد العنصر الأحدث أولاً ثم استخدمه .find, .children إلخ.: $('#foo').find('div')
  • الجزء الموجود في أقصى اليسار (الأول) من المحدد يستطيع يكون التحجيم أقل كفاءة إلى الجزء الموجود في أقصى اليمين (الأخير). يجب كن الأكثر كفاءة - بمعنى إذا لم يكن لديك بطاقة هوية فتأكد من أنك تبحث عنها $('div.common[slow*=Search] input.rare') بدلا من $('div.rare input.common[name*=slowSearch]') - نظرًا لأن هذا لا ينطبق دائمًا، تأكد من فرض ترتيب المحدد عن طريق التقسيم وفقًا لذلك.

لكي تفهم بشكل كامل ما هو الأسرع، عليك أن تفهم كيفية عمل محلل CSS.

يتم تقسيم المحدد الذي تقوم بتمريره إلى أجزاء يمكن التعرف عليها باستخدام RegExp ثم تتم معالجته قطعة قطعة.

تستخدم بعض المحددات، مثل ID وTagName، التنفيذ الأصلي للمتصفح وهو أسرع.بينما تتم برمجة برامج أخرى مثل الفئة والسمات بشكل منفصل وبالتالي فهي أبطأ بكثير، مما يتطلب تكرار العناصر المحددة والتحقق من اسم كل فئة.

لذا نعم للإجابة على سؤالك:

$('tag.class') أسرع من $('.class') فقط.لماذا؟في الحالة الأولى، يستخدم jQuery تطبيق المتصفح الأصلي لتصفية التحديد وصولاً إلى العناصر التي تحتاجها فقط.عندها فقط يتم تشغيل تطبيق .class الأبطأ وصولاً إلى ما طلبته.

في الحالة الثانية، يستخدم jQuery طريقته لتصفية كل عنصر عن طريق الاستيلاء على الفئة.

ينتشر هذا أبعد من jQuery حيث تعتمد جميع مكتبات جافا سكريبت على هذا.الخيار الآخر الوحيد هو استخدام xPath ولكنه غير مدعوم حاليًا بشكل جيد بين جميع المتصفحات.

إليك كيفية تحسين أداء محددات jQuery الخاصة بك:

سأضيف ملاحظة أنه في 99% من تطبيقات الويب، حتى تطبيقات أجاكس الثقيلة، ستؤدي سرعة الاتصال واستجابة خادم الويب إلى زيادة أداء تطبيقك بدلاً من جافا سكريبت.أنا لا أقول أنه يجب عليك كتابة تعليمات برمجية بطيئة عن عمد أو أن إدراك الأشياء التي من المحتمل أن تكون أسرع من غيرها ليس أمرًا جيدًا.

لكنني أتساءل عما إذا كنت تحاول حل مشكلة غير موجودة بالفعل بعد، أو حتى إذا كنت تقوم بتحسين شيء قد يكون يتغير في المستقبل القريب (على سبيل المثال، إذا بدأ المزيد من الأشخاص في استخدام متصفح يدعم getElementsByClassName() الوظيفة المشار إليها سابقًا)، مما يجعل التعليمات البرمجية المحسنة الخاصة بك تعمل بشكل أبطأ.

مكان آخر للبحث عن معلومات الأداء هو صفحة تحليل أداء المحددات الخاصة بـ Hugo Vidal Teixeira.

http://www.componenthouse.com/article-19

وهذا يوفر سرعة جيدة للمحدد حسب المعرف، والمحدد حسب الفئة، واسم علامة بادئة المحدد.

أسرع المحددات حسب المعرف كانت:$("#id")

أسرع محدد حسب الفئة كان:$('tag.class')

لذا فإن البادئة بالعلامة تساعد فقط عند الاختيار حسب الفصل!

لقد كنت عضوًا في بعض قوائم بريد jQuery ومن ما قرأته هناك، فمن المرجح أنهم يقومون بالتصفية حسب اسم العلامة ثم اسم الفئة (أو العكس إذا كان أسرع).إنهم مهووسون بالسرعة وسيستخدمون أي شيء للحصول على قدر ضئيل من الأداء.

أنا حقًا لن أقلق بشأن هذا الأمر كثيرًا على أي حال إلا إذا كنت تقوم بتشغيل هذا المحدد آلاف المرات/الثانية.

إذا كنت مهتمًا حقًا، فحاول إجراء بعض الاختبارات المرجعية ومعرفة أيهما أسرع.

فكر في استخدام مكتبة Oliver Steele Sequentially لاستدعاء الأساليب بمرور الوقت بدلاً من استدعائها دفعة واحدة.

http://ostele.com/sources/javascript/sequentially/

تساعدك الطريقة "النهائية" على استدعاء الطريقة بعد فترة زمنية معينة من استدعائها الأولي.تتيح لك الطريقة "بالتسلسل" وضع عدة مهام في قائمة الانتظار خلال فترة زمنية.

مفيد جدا!

أ نصيحة عظيمة من سؤال سألته:يستخدم محددات CSS القياسية حيثما كان ذلك ممكنا.يسمح هذا لـ jQuery باستخدام واجهة برمجة تطبيقات المحددات.وفق الاختبارات التي أجراها جون ريسيج, ، يؤدي هذا إلى أداء قريب من الأداء الأصلي للمحددات.وظائف مثل :has() و :contains() يجب اجتنابها.

من خلال بحثي، تم تقديم الدعم لواجهة برمجة تطبيقات Selectors مع jQuery 1.2.7 وFirefox 3.1 وIE 8 وOpera 10 وSafari 3.1.

إذا لم أكن مخطئًا، فإن jQuery أيضًا هو محرك من الأسفل إلى الأعلى.هذا يعني $('#foo bar div') أبطأ بكثير من $('bar div #foo').على سبيل المثال، $('#foo a') سوف تمر بكل a العناصر الموجودة على الصفحة ومعرفة ما إذا كان لديهم سلف #foo, ، مما يجعل هذا المحدد غير فعال إلى حد كبير.

ربما يكون Resig قد قام بالفعل بتحسين هذا السيناريو (لن يفاجئني إذا فعل ذلك - أعتقد أنه فعل ذلك في محرك Sizzle الخاص به، لكنني لست متأكدًا بنسبة 100٪.)

أعتقد أن الاختيار حسب المعرف أولاً يكون دائمًا أسرع:

$("#myform th").css("color","red");

ينبغي أن يكون أسرع من

$("th").css("color","red");

ومع ذلك، أتساءل ما مدى فائدة التسلسل عند البدء بالمعرف؟هذا هو

$("#myform").find("th").css("color","red")
.end().find("td").css("color","blue");

أي أسرع من هذا؟

$("#myform th").css("color","red");
$("#myform td").css("color","blue");
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top