تصحيح أخطاء الأداء في الحقل

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

توفّر Google فئتَين من الأدوات لقياس الأداء وتصحيح أخطائه:

  • أدوات البرنامج المعملي: أدوات مثل Lighthouse، حيث يتم تحميل صفحتك في بيئة مُحاكية يمكنها محاكاة ظروف مختلفة (على سبيل المثال، شبكة بطيئة وجهاز جوّال منخفض المواصفات).
  • الأدوات الميدانية: أدوات مثل تقرير تجربة المستخدم على Chrome ( CrUX) الذي يستند إلى بيانات المستخدمين الفعلية المجمَّعة من Chrome. (يُرجى العلم أنّه يتم الحصول على البيانات الفعلية التي يتم الإبلاغ عنها من خلال أدوات مثل إحصاءات PageSpeed وSearch Console من بيانات CrUX).

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

تمثّل بيانات CrUX الأداء الحقيقي لصفحتك، ولكن من غير المرجح أن تساعدك معرفة نتائج CrUX في معرفة كيفية تحسين أدائك.

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

ويطرح هذا السؤال سؤالاً مهمًا: كيف يمكن الحصول على معلومات تصحيح الأخطاء لمؤشرات أداء الويب الأساسية أو غيرها من مقاييس الأداء من مستخدمين حقيقيين في هذا المجال؟

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

واجهات برمجة التطبيقات لتحديد المصدر وتصحيح الأخطاء

متغيّرات التصميم التراكمية (CLS)

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

ننصحك بالاطّلاع على التقرير التالي من "إحصاءات PageSpeed":

تقرير إحصاءات PageSpeed يحتوي على قيم مختلفة لمتغيّرات التصميم التراكمية (CLS)

إنّ القيمة التي تم الإبلاغ عنها لـ CLS من المختبر (Lighthouse) مقارنةً بمتغيّرات التصميم التراكمية (CLS) من الحقل (بيانات CrUX) مختلفة تمامًا، وهذا منطقيّ إذا كنت تعتبر أنّ الصفحة قد تتضمّن الكثير من المحتوى التفاعلي الذي لا يتم استخدامه عند اختباره في Lighthouse.

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

وتجعل واجهة LayoutShiftAttribution هذا الأمر ممكنًا.

الحصول على إحالة متغيّرات التصميم

يتم عرض واجهة LayoutShiftAttribution في كل إدخال layout-shift تصدره واجهة برمجة تطبيقات عدم استقرار التنسيق.

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

إليك بعض الأمثلة عن التعليمات البرمجية التي تسجل كل متغيّرات التصميم بالإضافة إلى العناصر التي تم تحويلها:

new PerformanceObserver((list) => {
  for (const {value, startTime, sources} of list.getEntries()) {
    // Log the shift amount and other entry info.
    console.log('Layout shift:', {value, startTime});
    if (sources) {
      for (const {node, curRect, prevRect} of sources) {
        // Log the elements that shifted.
        console.log('  Shift source:', node, {curRect, prevRect});
      }
    }
  }
}).observe({type: 'layout-shift', buffered: true});

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

ليس الهدف تحديد وإصلاح كل متغيّرات التصميم التي تحدث لكل مستخدم، بل الهدف هو تحديد التغيّرات التي تؤثر على أكبر عدد من المستخدمين وبالتالي المساهمة بأكبر قدر في متغيّرات التصميم التراكمية (CLS) لصفحتك عند النسبة المئوية الخامسة والسبعين.

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

يتضمّن الرمز التالي قائمة بإدخالات layout-shift ساهمت في متغيّرات التصميم التراكمية (CLS) وتعرض أكبر عنصر مصدر من أكبر عملية تبديل:

function getCLSDebugTarget(entries) {
  const largestEntry = entries.reduce((a, b) => {
    return a && a.value > b.value ? a : b;
  });
  if (largestEntry && largestEntry.sources && largestEntry.sources.length) {
    const largestSource = largestEntry.sources.reduce((a, b) => {
      return a.node && a.previousRect.width * a.previousRect.height >
          b.previousRect.width * b.previousRect.height ? a : b;
    });
    if (largestSource) {
      return largestSource.node;
    }
  }
}

بمجرد تحديد العنصر الأكبر الذي يساهم في أكبر نوبة عمل، يمكنك إبلاغ أداة الإحصاءات بذلك.

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

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

بعض بيانات التعريف الأخرى التي قد يكون من المفيد تسجيلها إلى جانب أكبر عنصر مصدر Shift هو:

  • وقت أكبر نوبة عمل
  • مسار عنوان URL في وقت حدوث أكبر تغيير (للمواقع الإلكترونية التي تعدّل عنوان URL ديناميكيًا، مثل تطبيقات الصفحة الواحدة).

سرعة عرض أكبر جزء من المحتوى على الصفحة (LCP)

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

يُرجى العِلم أنّه من الممكن تمامًا أن يكون العنصر المرشَّح لمقياس LCP مختلفًا من مستخدم إلى آخر، حتى على الصفحة نفسها.

ثمة أسباب متعدّدة لحدوث ذلك:

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

وهذا يعني أنّه لا يمكنك وضع افتراضات حول العنصر أو مجموعة العناصر التي ستكون العنصر الأكثر شيوعًا المرشَّح لمقياس LCP لصفحة معيّنة. وعليك قياسها استنادًا إلى سلوك المستخدم الحقيقي.

تحديد العنصر المرشح لسرعة عرض أكبر جزء من المحتوى على الصفحة (LCP)

لتحديد العنصر المرشَّح لسرعة عرض أكبر جزء من المحتوى على الصفحة (LCP) في JavaScript، يمكنك استخدام أكبر واجهة برمجة تطبيقات لسرعة عرض أكبر جزء من المحتوى على الصفحة، وهي واجهة برمجة التطبيقات نفسها التي تستخدمها لتحديد قيمة وقت سرعة عرض أكبر جزء من المحتوى على الصفحة.

عند ملاحظة إدخالات largest-contentful-paint، يمكنك تحديد العنصر المرشح الحالي لمقياس LCP بالاطّلاع على السمة element للإدخال الأخير:

new PerformanceObserver((list) => {
  const entries = list.getEntries();
  const lastEntry = entries[entries.length - 1];

  console.log('LCP element:', lastEntry.element);
}).observe({type: 'largest-contentful-paint', buffered: true});

بعد أن تعرِف العنصر المرشح لمقياس LCP، يمكنك إرساله إلى أداة الإحصاءات مع قيمة المقياس. وكما هي الحال مع متغيّرات التصميم التراكمية (CLS)، سيساعدك ذلك في تحديد العناصر الأهم لتحسينها أولاً.

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

مهلة الاستجابة لأوّل إدخال (FID)

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

على سبيل المثال، تعرض العديد من تطبيقات JavaScript التي توفّر العرض من جهة الخادم (SSR) لغة HTML ثابتة يمكن عرضها على الشاشة قبل أن تتفاعل مع البيانات التي يدخلها المستخدم، أي قبل انتهاء تحميل محتوى JavaScript المطلوب لجعله تفاعليًا.

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

إذا كان إطار عمل التطبيق يعرض الطابع الزمني لشرب الماء، يمكنك مقارنته بالطابع الزمني لإدخال first-input لتحديد ما إذا كان قد تم الإدخال الأول قبل شُرب الماء والسوائل أو بعده. وإذا لم يعرض إطار العمل ذلك الطابع الزمني، أو لا يستخدم ميزة شُرب الماء والسوائل على الإطلاق، قد تكون إحدى الإشارات المفيدة ما إذا تمّ إدخال البيانات قبل أو بعد انتهاء تحميل JavaScript.

يتم تنشيط حدث DOMContentLoaded بعد اكتمال تحميل وتحليل رمز HTML للصفحة بالكامل، ويشمل ذلك انتظار تحميل أي نصوص برمجية متزامنة أو مؤجلة أو وحدات (بما في ذلك جميع الوحدات المستوردة بشكل ثابت). لذلك يمكنك استخدام توقيت هذا الحدث ومقارنتها بوقت حدوث FID.

يراقب الرمز التالي إدخالات وسجلّات first-input ممّا إذا كان الإدخال الأول قد حدث قبل نهاية حدث DOMContentLoaded أم لا:

new PerformanceObserver((list) => {
  const fidEntry = list.getEntries()[0];
  const navEntry = performance.getEntriesByType('navigation')[0];
  const wasFIDBeforeDCL =
    fidEntry.startTime < navEntry.domContentLoadedEventStart;

  console.log('FID occurred before DOMContentLoaded:', wasFIDBeforeDCL);
}).observe({type: 'first-input', buffered: true});

تحديد العنصر المستهدف ونوع الحدث لمهلة الاستجابة الأولى (FID)

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

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

للحصول على نوع التفاعل والعنصر المرتبط بحدث الإدخال الأول، يمكنك الرجوع إلى السمتَين target وname لإدخال first-input:

new PerformanceObserver((list) => {
  const fidEntry = list.getEntries()[0];

  console.log('FID target element:', fidEntry.target);
  console.log('FID interaction type:', fidEntry.name);
}).observe({type: 'first-input', buffered: true});

مدى استجابة الصفحة لتفاعلات المستخدم (INP)

يتشابه INP إلى حد كبير مع FID في أن أهم وحدات المعلومات التي يجب الحصول عليها في الحقل هي:

  1. العنصر الذي تم التفاعل معه
  2. لماذا كان نوع التفاعل
  3. وقت حدوث ذلك التفاعل

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

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

بما أنّ INP وFID يستندان إلى Event Timing API، إنّ الطريقة التي تحدد بها هذه المعلومات في JavaScript مشابهة جدًا للمثال السابق. ويسجل الرمز التالي العنصر والوقت المستهدفَين (بالنسبة إلى DOMContentLoaded) لإدخال INP.

function logINPDebugInfo(inpEntry) {
  console.log('INP target element:', inpEntry.target);
  console.log('INP interaction type:', inpEntry.name);

  const navEntry = performance.getEntriesByType('navigation')[0];
  const wasINPBeforeDCL =
    inpEntry.startTime < navEntry.domContentLoadedEventStart;

  console.log('INP occurred before DCL:', wasINPBeforeDCL);
}

يُرجى العِلم أنّ هذا الرمز لا يوضّح طريقة تحديد إدخال event الذي يمثّل إدخال INP، لأن هذا المنطق أكثر تعمقًا. ومع ذلك، يوضّح القسم التالي طريقة الحصول على هذه المعلومات باستخدام مكتبة JavaScript لـ web-vitals.

الاستخدام مع مكتبة JavaScript لدعوات الويب

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

منذ الإصدار 3، تشتمل مكتبة VP-Fis في JavaScript على بنية إحالة تعرض كل هذه المعلومات، وعدد قليل من الإشارات الإضافية أيضًا.

يوضّح مثال الرمز التالي كيفية إعداد مَعلمة حدث إضافية (أو سمة مخصّصة) تحتوي على سلسلة تصحيح أخطاء مفيدة للمساعدة في تحديد السبب الرئيسي لمشاكل الأداء.

import {onCLS, onFID, onINP, onLCP} from 'web-vitals/attribution';

function sendToGoogleAnalytics({name, value, id, attribution}) {
  const eventParams = {
    metric_value: value,
    metric_id: id,
  }

  switch (name) {
    case 'CLS':
      eventParams.debug_target = attribution.largestShiftTarget;
      break;
    case 'LCP':
      eventParams.debug_target = attribution.element;
      break;
    case 'FID':
    case 'INP':
      eventParams.debug_target = attribution.eventTarget;
      break;
  }

  // Assumes the global `gtag()` function exists, see:
  // https://developers.google.com/analytics/devguides/collection/ga4
  gtag('event', name, eventParams);
}

onCLS(sendToGoogleAnalytics);
onLCP(sendToGoogleAnalytics);
onFID(sendToGoogleAnalytics);
onINP(sendToGoogleAnalytics);

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

يعرِض هذا الرمز أيضًا كيفية إعداد التقارير عن إشارة تصحيح أخطاء واحدة، ولكن قد يكون من المفيد أن تتمكّن من جمع عدّة إشارات مختلفة لكل مقياس وإعداد تقارير عنها. على سبيل المثال، لتصحيح أخطاء INP، قد تحتاج إلى جمع نوع التفاعل والوقت والعنصر الذي يتم التفاعل معه. ويعرض نموذج تحديد المصدر web-vitals كل هذه المعلومات، كما هو موضّح في المثال التالي:

import {onCLS, onFID, onINP, onLCP} from 'web-vitals/attribution';

function sendToGoogleAnalytics({name, value, id, attribution}) {
  const eventParams = {
    metric_value: value,
    metric_id: id,
  }

  switch (name) {
    case 'INP':
      eventParams.debug_target = attribution.eventTarget;
      eventParams.debug_type = attribution.eventType;
      eventParams.debug_time = attribution.eventTime;
      eventParams.debug_load_state = attribution.loadState;
      break;

    // Additional metric logic...
  }

  // Assumes the global `gtag()` function exists, see:
  // https://developers.google.com/analytics/devguides/collection/ga4
  gtag('event', name, eventParams);
}

onCLS(sendToGoogleAnalytics);
onLCP(sendToGoogleAnalytics);
onFID(sendToGoogleAnalytics);
onINP(sendToGoogleAnalytics);

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

إعداد تقرير عن البيانات وتصورها

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

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

بالنسبة إلى "إحصاءات Google 4"، راجِع المقالة المخصّصة حول كيفية الاستعلام عن البيانات وعرضها باستخدام BigQuery.

ملخّص

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

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

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

أخيرًا، إذا كنت تعتقد أنّ هناك ثغرات في قدرتك على تصحيح الأخطاء في هذه المقاييس بسبب نقص الميزات أو المعلومات في واجهات برمجة التطبيقات نفسها، يمكنك إرسال ملاحظاتك إلى web-vitals-feedback@googlegroups.com.