تصحيح الأخطاء في متغيّرات التصميم

تعرَّف على كيفية تحديد تغيُّرات التنسيق وإصلاحها.

Katie Hempenius
Katie Hempenius

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

الأدوات

واجهة برمجة التطبيقات Layout Instability API

واجهة برمجة التطبيقات Layout Instability API هي آلية المتصفّح لقياس متغيّرات التصميم والإبلاغ عنها. جميع أدوات debugging تغيُّرات التصميم، بما في ذلك DevTools، تستند في النهاية إلى واجهة برمجة التطبيقات Layout Instability API. ومع ذلك، يُعدّ استخدام واجهة برمجة التطبيقات Layout Instability API مباشرةً أداة فعّالة لتصحيح الأخطاء بسبب مرونتها.

الاستخدام

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

let cls = 0;
new PerformanceObserver((entryList) => {
  for (const entry of entryList.getEntries()) {
    if (!entry.hadRecentInput) {
      cls += entry.value;
      console.log('Current CLS value:', cls, entry);
    }
  }
}).observe({type: 'layout-shift', buffered: true});

عند تشغيل هذا النص البرمجي، يُرجى مراعاة ما يلي:

  • يشير الخيار buffered: true إلى أنّه على العنصر PerformanceObserver التحقّق من مخطّط تخزين إدخالات الأداء في المتصفّح بحثًا عن إدخالات الأداء التي تم إنشاؤها قبل تهيئة المراقب. نتيجةً لذلك، سيُبلغ PerformanceObserver عن التحولات في ملف التنسيق التي حدثت قبل بدء التشغيل وبعده. يُرجى مراعاة ذلك عند فحص سجلّات وحدة التحكّم. يمكن أن يعكس العدد الكبير من عمليات تغيير التنسيق في البداية تأخّر إعداد التقارير، بدلاً من حدوث العديد من عمليات تغيير التنسيق بشكل مفاجئ.
  • لتجنّب التأثير في الأداء، ينتظر PerformanceObserver إلى أن يصبح مثيل السلسلة الأساسي غير نشِط لإعداد تقارير عن تغييرات التنسيق. ونتيجةً لذلك، استنادًا إلى مدى مشغولية السلسلة الرئيسية، قد يحدث تأخير طفيف بين وقت حدوث عملية تغيير التنسيق ووقت تسجيلها في وحدة التحكّم.
  • يتجاهل هذا النص البرمجي تغييرات التنسيق التي حدثت خلال 500 ملي ثانية من إدخال المستخدم، وبالتالي لا يتم احتسابها ضمن مقياس CLS.

يتم تسجيل معلومات عن عمليات تغيير التنسيق باستخدام واجهتَي برمجة التطبيقات: LayoutShift و LayoutShiftAttribution. يتم شرح كل واجهة من هذه الواجهات بمزيد من التفصيل في ال أقسام التالية.

LayoutShift

يتم تسجيل كلّ تغيير في التنسيق باستخدام واجهة LayoutShift. تظهر محتويات إدخال على النحو التالي:

duration: 0
entryType: "layout-shift"
hadRecentInput: false
lastInputTime: 0
name: ""
sources: (3) [LayoutShiftAttribution, LayoutShiftAttribution, LayoutShiftAttribution]
startTime: 11317.934999999125
value: 0.17508567530168798

يشير الإدخال أعلاه إلى تغيير في التنسيق خلال عملية تغيّر فيها مثبّت عنصرَي DOM. كانت نتيجة متغيّرات التصميم لمتغيّرات التصميم هذه هي 0.175.

في ما يلي خصائص مثيل LayoutShift الأكثر صلةً بمحاولة تصحيح أخطاء متغيّرات التصميم:

الموقع الوصف
sources تعرض السمة sources عناصر نموذج DOM التي تم نقلها أثناء تغيير التنسيق. يمكن أن يحتوي هذا الصفيف على ما يصل إلى خمسة مصادر. في حال توفّر أكثر من خمسة عناصر متأثرة بمتغيّرات التصميم، يتم تسجيل أكبر خمسة مصادر لمتغيّرات التصميم (يتم قياسها حسب التأثير في ثبات التصميم). ويتم تسجيل هذه المعلومات باستخدام واجهة LayoutShiftAttribution (يتم شرحها بالتفصيل أدناه).
value يُبلغ موقع value عن نتيجة متغيّرات التصميم لمتغيّرات تصميم معيّنة.
hadRecentInput تشير السمة hadRecentInput إلى ما إذا حدث تغيير في التصميم خلال 500 ملي ثانية من إدخال المستخدم.
startTime يشير الحقل startTime إلى وقت حدوث تغيير في التنسيق. يتمّ التعبير عن startTime بالمللي ثانية ويتم قياسه نسبةً إلى الوقت الذي بدأ فيه تحميل الصفحة.
duration سيتم ضبط السمة duration دائمًا على 0. يتم اكتساب هذه السمة من واجهة PerformanceEntry (تُوسّع واجهة LayoutShift واجهة PerformanceEntry). ومع ذلك، لا ينطبق مفهوم المدة على أحداث تغيير التنسيق، لذا يتم ضبطه على 0. للحصول على معلومات عن واجهة PerformanceEntry، يُرجى الرجوع إلى المواصفات.

LayoutShiftAttribution

تصف واجهة LayoutShiftAttribution عملية نقل واحدة لعنصر DOM واحد. إذا تمّ نقل عناصر متعدّدة أثناء تغيير التنسيق، تحتوي السمة sources على إدخالات متعدّدة.

على سبيل المثال، يتوافق تنسيق JSON أدناه مع تغيير في التنسيق من مصدر واحد: الانتقال للأسفل لعنصر <div id='banner'> DOM من y: 76 إلى y:246.

// ...
  "sources": [
    {
      "node": "div#banner",
      "previousRect": {
        "x": 311,
        "y": 76,
        "width": 4,
        "height": 18,
        "top": 76,
        "right": 315,
        "bottom": 94,
        "left": 311
      },
      "currentRect": {
        "x": 311,
        "y": 246,
        "width": 4,
        "height": 18,
        "top": 246,
        "right": 315,
        "bottom": 264,
        "left": 311
      }
    }
  ]

تحدّد السمة node عنصر HTML الذي تم نقله. يؤدي تمرير مؤشر الماوس فوق هذه السمة في أدوات مطوّري البرامج إلى تمييز عنصر الصفحة المقابل.

تُبلِغ السمتَان previousRect وcurrentRect عن حجم العقدة وموضعها.

  • تُستخدَم الإحداثيتان x وy لعرض إحداثي x وإحداثي y للزاوية العلوية اليسرى من العنصر على التوالي.
  • تعرض السمتان width وheight عرض العنصر وارتفاعه على التوالي.
  • تُبلِغ سمات top وright وbottom وleft عن قيم إحداثي x أو y المتوافقة مع الحافة المحدّدة للعنصر. بعبارة أخرى، قيمة top تساوي y، وقيمة bottom تساوي y+height.

إذا تم ضبط جميع سمات previousRect على 0، يعني ذلك أنّه تم نقل العنصر إلى العرض. إذا تم ضبط جميع سمات currentRect على 0، يعني ذلك أنّ العنصر قد تم نقله خارج نطاق العرض.

من أهم الأمور التي يجب فهمها عند تفسير هذه النتائج هو أنّ العناصر المُدرَجة على أنّها مصادر هي العناصر التي تمّ نقلها أثناء تغيير التنسيق. ومع ذلك، من الممكن أن تكون هذه العناصر مرتبطة فقط بشكل غير مباشر بـ "السبب الأساسي" لعدم استقرار التنسيق. وفي ما يلي بعض الأمثلة.

المثال 1

سيتم تسجيل هذا التحول في التنسيق باستخدام مصدر واحد: العنصر "ب". ومع ذلك، فإنّ السبب الأساسي لتغيير التنسيق هذا هو التغيير في حجم العنصر "أ".

مثال يعرض تغييرًا في التنسيق ناتجًا عن تغيير في سمات العنصر

المثال 2

سيتم تسجيل تغيير التنسيق في هذا المثال من خلال مصدرَين: العنصر "أ" والعنصر "ب". السبب الأساسي لمتغيّرات التصميم هذه هو التغيير في موضع العنصر "أ".

مثال يعرض تغييرًا في التنسيق ناتجًا عن تغيير في موضع العنصر

المثال 3

سيتم تسجيل تغيُّر التنسيق في هذا المثال من خلال مصدر واحد: العنصر "ب". أدّى تغيير موضع العنصر "ب" إلى حدوث هذا التغيُّر في التنسيق.

مثال يعرض تغييرًا في التنسيق ناتجًا عن تغيير في موضع العنصر

المثال 4

على الرغم من أنّ حجم العنصر "ب" يتغيّر، لا يحدث أيّ تغيير في التنسيق في هذا المثال.

مثال يعرض عنصرًا يتغيّر حجمه ولكنّه لا يتسبب في تغيير التنسيق

يمكنك الاطّلاع على عرض توضيحي لكيفية تسجيل تغييرات DOM من خلال Layout Instability API.

أدوات مطوري البرامج

لوحة الأداء

تعرِض لوحة التجربة في لوحة الأداء في "أدوات المطوّرين" كلّ تغييرات التصميم التي تحدث أثناء تتبُّع أداء معيّن، حتى إذا حدثت خلال 500 ملي ثانية من تفاعل المستخدم، وبالتالي لا يتم احتسابها ضمن مقياس CLS. يؤدي تمرير مؤشّر الماوس فوق متغيّر تصميم معيّن في لوحة التجربة إلى تمييز عنصر DOM المتأثّر.

لقطة شاشة لتغيير تنسيق معروض في لوحة &quot;الشبكة&quot; في DevTools

للاطّلاع على مزيد من المعلومات عن تغيُّر التصميم، انقر على تغيُّر التصميم، ثم افتح الدرج الملخّص. يتم إدراج التغييرات على أبعاد العنصر باستخدام التنسيق [width, height]، ويتم إدراج التغييرات على موضع العنصر باستخدام التنسيق [x,y]. تشير السمة Had recent input إلى ما إذا كان هناك تغيير في التنسيق خلال 500 ملي ثانية من تفاعل المستخدِم.

لقطة شاشة لعلامة التبويب &quot;الملخّص&quot; في DevTools لتغيُّر في التنسيق

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

لقطة شاشة لعلامة التبويب &quot;سجلّ الأحداث&quot; في DevTools لمتغيّرات التصميم

لمزيد من المعلومات عن استخدام لوحة الأداء، يُرجى الرجوع إلى مرجع تحليل الأداء.

تسليط الضوء على مناطق التغيّر في التصميم

يمكن أن يكون تمييز مناطق متغيّرات التصميم من الأساليب المفيدة للحصول على تصوّر سريع ومباشر عن الموقع الجغرافي وتوقيت متغيّرات التصميم التي تحدث في الصفحة.

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

عملية التفكير لتحديد سبب حدوث تغييرات في التنسيق

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

تحديد سبب تغيُّر التنسيق

يمكن أن تحدث تغييرات في التنسيق بسبب الأحداث التالية:

  • التغييرات في موضع عنصر DOM
  • التغييرات في سمات عنصر DOM
  • إدراج عنصر DOM أو إزالته
  • الصور المتحركة التي تؤدي إلى عرض التنسيق

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

  • هل تغيّر موضع العنصر السابق أو أبعاده؟
  • هل تم إدراج عنصر DOM أو إزالته قبل العنصر الذي تم نقله؟
  • هل تم تغيير موضع العنصر الذي تم نقله صراحةً؟

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

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

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

في ما يلي بعض السلوكيات المحدّدة التي تتسبّب في أحداث تغيُّر التصميم بشكلٍ متكرّر:

التغييرات في موضع عنصر (التي لا ترجع إلى حركة عنصر آخر)

غالبًا ما يكون هذا النوع من التغييرات نتيجةً لما يلي:

  • جداول الأنماط التي يتم تحميلها متأخرًا أو تستبدل الأنماط التي تمّ الإعلان عنها سابقًا
  • تأثيرات الرسوم المتحركة والانتقالات

التغييرات في سمات العنصر

غالبًا ما يكون هذا النوع من التغييرات نتيجةً لما يلي:

  • جداول الأنماط التي يتم تحميلها متأخرًا أو تستبدل الأنماط التي تمّ الإعلان عنها سابقًا
  • الصور وإطارات iframe التي لا تحتوي على سمتَي width وheight والتي يتم تحميلها بعد عرض "مكانها"
  • مجموعات النصوص التي لا تتضمّن سمتَي width أو height وتبدّل الخطوط بعد عرض النص

إدراج عناصر DOM أو إزالتها

غالبًا ما يكون ذلك نتيجةً لما يلي:

  • إدراج الإعلانات والمحتوى المضمّن الآخر التابع لجهات خارجية
  • إدراج إعلانات البانر والتنبيهات والنوافذ المنبثقة
  • التمرير اللا نهائي وأنماط تجربة المستخدم الأخرى التي تحمّل محتوى إضافيًا فوق المحتوى الحالي

الصور المتحركة التي تؤدي إلى عرض التنسيق

يمكن أن تؤدي تأثيرات التحريك إلى تغيير التنسيق. ومن الأمثلة الشائعة على ذلك عندما يتم "تحريك" عناصر DOM من خلال زيادة القيم مثل top أو left بدلاً من استخدام سمة CSS transform. اطّلِع على كيفية إنشاء صور متحركة عالية الأداء باستخدام CSS لمزيد من المعلومات.

إعادة إنشاء تغييرات التصميم

لا يمكنك إصلاح تغييرات التنسيق التي لا يمكنك إعادة إنتاجها. من أبسط الإجراءات التي يمكنك اتّخاذها، وأحد أكثرها فعالية في الوقت نفسه، للتعرّف بشكل أفضل على ثبات تنسيق موقعك الإلكتروني هو تخصيص 5 إلى 10 دقائق للتفاعل مع موقعك الإلكتروني بهدف بدء تغييرات التنسيق. اترك وحدة التحكّم مفتوحة أثناء إجراء ذلك واستخدِم واجهة برمجة التطبيقات Layout Instability API لإعداد تقارير عن تغييرات التنسيق.

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

new PerformanceObserver((entryList) => {
  for (const entry of entryList.getEntries()) {
    if (!entry.hadRecentInput) {
      cls += entry.value;
      debugger;
      console.log('Current CLS value:', cls, entry);
    }
  }
}).observe({type: 'layout-shift', buffered: true});

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