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

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

Katie Hempenius
Katie Hempenius

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

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

واجهة برمجة التطبيقات Layout Instability API هي آلية المتصفّح لقياس متغيّرات التصميم والإبلاغ عنها. تم إنشاء جميع الأدوات الخاصة بتصحيح أخطاء متغيّرات التصميم، بما في ذلك "أدوات مطوري البرامج"، استنادًا إلى واجهة برمجة التطبيقات 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

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

مثال يعرض تغيُّر تصميم ناتج عن تغيير في أبعاد العناصر

المثال الثاني

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

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

المثال 3

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

مثال يعرض متغيّرات التصميم الناتج عن تغيير في موضع العنصر

المثال الرابع

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

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

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

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

لوحة الأداء

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

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

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

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

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

لقطة شاشة لعلامة التبويب &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 مع أداة تسجيل الواجهة الأمامية من اختيارك لجمع مزيد من المعلومات عن هذه المشاكل. اطّلِع على مثال الرمز البرمجي لكيفية تتبُّع أكبر عنصر تم نقله على الصفحة.