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

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

كاتي هيمبينيوس
"كاتي هيمبينيوس"

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

الأدوات

واجهة برمجة تطبيقات عدم استقرار التنسيق

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، يُرجى الرجوع إلى spec.

LayoutShiftAttribution

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

على سبيل المثال، يتجاوب ملف JSON أدناه مع متغيّرات التصميم ذات المصدر الواحد، وهو الإزاحة المتّجهة للأسفل لعنصر DOM <div id='banner'> من 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 الإحداثي السيني والإحداثي y على التوالي للزاوية العلوية اليسرى من العنصر
  • تُبلغ السمتان width وheight عن عرض العنصر وارتفاعه على التوالي.
  • تسجّل الخصائص top وright وbottom وleft قيم الإحداثي x أو y المقابلة لحافة العنصر المحددة. بعبارة أخرى، تساوي قيمة top y وتساوي bottom y+height.

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

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

المثال الأول

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

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

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

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

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

المثال الثالث

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

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

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

على الرغم من تغيير حجم العنصر B، لا يوجد تغيُّر في التخطيط في هذا المثال.

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

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

DevTools

لوحة الأداء

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

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

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

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

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

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

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

تمييز مناطق متغيّرات التصميم

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

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

عملية التفكير لتحديد سبب متغيرات التصميم

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

تحديد سبب تغيُّر التصميم

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

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

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

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

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

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

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

فيما يلي بعض السلوكيات المحددة التي تؤدي غالبًا إلى أحداث تغيُّر التصميم:

التغييرات التي تطرأ على موضع عنصر (ليس بسبب حركة عنصر آخر)

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

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

التغييرات التي تطرأ على أبعاد العنصر

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

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

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

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

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

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

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

إعادة إنتاج متغيّرات التصميم

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

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