تقليل نطاق وتعقيد العمليات الحسابية للأنماط

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

حساب النمط

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

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

وقت إعادة احتساب النمط ووقت استجابة التفاعل

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

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

التقليل من تعقيد أدوات الاختيار

يمكن أن يساعد تبسيط أسماء أدوات الاختيار في تسريع العمليات الحسابية للأنماط في صفحتك. تشير أبسط أدوات الاختيار إلى عنصر في CSS باسم فئة فقط:

.title {
  /* styles */
}

ومع نمو أيّ مشروع، من المرجّح أن يحتاج إلى لغة CSS أكثر تعقيدًا، وقد ينتهي بك الأمر باستخدام أدوات اختيار تشبه ما يلي:

.box:nth-last-child(-n+1) .title {
  /* styles */
}

لتحديد طريقة تطبيق هذه الأنماط على الصفحة، على المتصفّح أن يسأل: "هل هذا العنصر يحتوي على فئة title ومصدره الرئيسي هو العنصر الفرعي ناقص nth-plus-1 وفئة box؟". ويمكن أن يستغرق حلّ هذه المشكلة وقتًا طويلاً، حسب أداة الاختيار المستخدَمة والمتصفّح المعنيّ. لتبسيط ذلك، يمكنك تغيير أداة الاختيار لتكون اسم فئة فقط:

.final-box-title {
  /* styles */
}

وقد تبدو أسماء الفئات البديلة هذه محرجة، ولكنها تجعل مهمة المتصفح أبسط كثيرًا. في الإصدار السابق مثلاً، لكي يعرف المتصفّح أنّ العنصر هو الأخير من نوعه، يجب أن يعرف أولاً كل شيء عن جميع العناصر الأخرى لتحديد ما إذا كانت أي عناصر تأتي بعده يمكن أن تكون nth-last-child. وقد يكون ذلك أكثر تكلفة من الناحية الحسابية بكثير من مطابقة محدد بعنصر لمجرد تطابق فئته.

تقليل عدد العناصر المراد تصميمها

هناك اعتبار آخر للأداء، وغالبًا ما يكون أكثر أهمية من تعقيد المحدد، وهو مقدار العمل الذي يجب أن يحدث عندما يتغير العنصر.

وبصفة عامة، إنّ أسوأ تكلفة لحساب نمط العناصر المحسوبة هي عدد العناصر مضروبًا بعدد المحدِّد، لأنّ المتصفّح يحتاج إلى فحص كل عنصر مرة واحدة على الأقل مقابل كل نمط لمعرفة ما إذا كان مطابقًا لعدد العناصر.

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

قياس تكلفة إعادة احتساب النمط

لقياس تكلفة عمليات إعادة احتساب الأنماط، يمكنك استخدام لوحة الأداء في "أدوات مطوري البرامج في Chrome". اتّبِع الخطوات التالية للبدء:

  1. افتح "أدوات مطوري البرامج".
  2. انتقِل إلى علامة التبويب الأداء.
  3. انقر على تسجيل.
  4. التفاعل مع الصفحة:

عند إيقاف التسجيل، ستظهر لك الصورة التالية:

أدوات مطوري البرامج تعرض العمليات الحسابية للأنماط
تقرير "أدوات مطوري البرامج" يعرض العمليات الحسابية للأنماط.

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

تكبير منطقة المشكلة في "أدوات مطوري البرامج في Chrome" ضمن ملخّص النشاط الخاص بلوحة الأداء التي تمت تعبئتها ضمن "أدوات مطوري البرامج في Chrome".
اللقطات الطويلة الأمد في ملخّص نشاط "أدوات مطوري البرامج"

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

الحصول على تفاصيل العمليات الحسابية للأنماط طويلة الأمد، بما في ذلك المعلومات الحيوية، مثل عدد العناصر التي تأثرت بعملية إعادة احتساب الأنماط
عملية إعادة احتساب طويلة الأمد للأنماط تستغرق أكثر من 25 ملي ثانية في ملخّص "أدوات مطوري البرامج"

ويؤدي النقر على الحدث إلى عرض حزمة المكالمات المتعلقة به. إذا كان عمل العرض ناتجًا من تفاعل المستخدم، فسيتم استدعاء JavaScript الذي أدى إلى تغيير النمط. كما يعرض عدد العناصر التي يؤثر عليها التغيير - أكثر من 900 عنصر فقط في هذه الحالة - والمدة التي استغرقتها حساب النمط. يمكنك استخدام هذه المعلومات لبدء محاولة العثور على إصلاح في التعليمات البرمجية الخاصة بك.

استخدام سياسة الحظر والعنصر والمعدِّل

إنّ الأساليب المستخدمة في الترميز مثل BEM (Block, Element, Modifier) تؤدي إلى دمج مزايا الأداء المطابقة في أداة الاختيار. يوصي BEM بأن يكون لكل شيء فئة واحدة، وحيث تحتاج إلى التسلسل الهرمي، يتم دمج هذا التسلسل الهرمي أيضًا في اسم الفئة:

.list {
  /* Styles */
}

.list__list-item {
  /* Styles */
}

إذا كنت بحاجة إلى معدِّل، كما في مثال العنصر الفرعي الأخير، يمكنك إضافة ذلك على النحو التالي:

.list__list-item--last-child {
  /* Styles */
}

يعتبر BEM نقطة انطلاق جيدة لتنظيم CSS، سواء من منظور بنية، أو بسبب تبسيطات البحث عن الأنماط التي يروج لها.

إذا كنت لا تحب BEM، هناك طرق أخرى للتعامل مع CSS، ولكن عليك تقييم أدائه وخصائصه الهندسية قبل البدء.

المراجِع

صورة رئيسية من UnLaunch، للفنان ماركوس سبيسك.