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

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

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

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

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

تمثّل بيانات تقرير تجربة المستخدم على Chrome الأداء الحقيقي لصفحتك، ولكن من غير المرجح أن تساعدك معرفة نتائج 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

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

عند ملاحظة إدخالات 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. إن معرفة ما إذا كانت معظم التفاعلات البطيئة تحدث أثناء تحميل الصفحة مفيدة في تحديد ما يجب فعله لإصلاح المشكلة.

وعلى عكس مقياس FID، يراعي مقياس 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، تتضمن مكتبة بيانات 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.