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

1. مقدمة

هذا هو الدرس التطبيقي التفاعلي حول الترميز للتعرّف على كيفية قياس مدى استجابة الصفحة لتفاعلات المستخدم (INP) باستخدام مكتبة web-vitals.

المتطلبات الأساسية

ما سوف تتعلمه

  • كيفية إضافة مكتبة web-vitals إلى صفحتك واستخدام بيانات تحديد المصدر الخاصة بها
  • يمكنك استخدام بيانات تحديد المصدر من أجل تشخيص موضع وكيفية بدء تحسين INP.

ما ستحتاجه

  • جهاز كمبيوتر لديه القدرة على استنساخ التعليمات البرمجية من GitHub وتنفيذ أوامر npm.
  • محرِّر نصوص
  • إصدار حديث من Chrome لكي تعمل جميع قياسات التفاعل.

2. الإعداد

الحصول على الرمز وتشغيله

يمكنك العثور على الرمز في مستودع web-vitals-codelabs.

  1. استنسِخ المستودع في الوحدة الطرفية: git clone https://github.com/GoogleChromeLabs/web-vitals-codelabs.git.
  2. الانتقال إلى الدليل المنسوخ: cd web-vitals-codelabs/measuring-inp
  3. تثبيت الملحقات: npm ci.
  4. ابدأ تشغيل خادم الويب: npm run start.
  5. انتقل إلى http://localhost:8080/ في متصفحك.

تجربة الصفحة

يستخدم هذا الدرس التطبيقي حول الترميز موقع Gastropodicon (موقع مرجعي شائع لتشريح الحلزون) لاستكشاف المشاكل المحتملة المتعلّقة بمقياس INP.

لقطة شاشة لصفحة Gastropodicon التجريبية

حاول التفاعل مع الصفحة للتعرف على التفاعلات البطيئة.

3- بدء استخدام "أدوات مطوري البرامج في Chrome"

افتح أدوات مطوري البرامج من المزيد من الأدوات > قائمة أدوات المطوّرين من خلال النقر بزر الماوس الأيمن على الصفحة واختيار فحص أو باستخدام اختصار لوحة مفاتيح

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

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

لقطة شاشة للوحة "أداء أدوات مطوّري البرامج" بجانب التطبيق، مع تحديد بطء وحدة المعالجة المركزية (CPU) بمقدار 4 مرات

4. جارٍ التثبيت web-vitals

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

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

سيتم تثبيت هذا الدرس التطبيقي حول الترميز من npm وتحميل النص البرمجي مباشرةً لتجنُّب التعمق في عملية تصميم معيّنة.

هناك إصداران من web-vitals يمكنك استخدامهما:

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

لقياس INP في هذا الدرس التطبيقي حول الترميز، نريد إنشاء نموذج تحديد المصدر.

إضافة web-vitals إلى devDependencies للمشروع من خلال تشغيل npm install -D web-vitals

إضافة web-vitals إلى الصفحة:

أضِف إصدار تحديد المصدر الخاص بالنص البرمجي إلى أسفل index.html وسجِّل النتائج في وحدة التحكّم:

<script type="module">
  import {onINP} from './node_modules/web-vitals/dist/web-vitals.attribution.js';

  onINP(console.log);
</script>

جرّبه الآن

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

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

يوفّر web-vitals الخيار reportAllChanges لإعداد تقارير أكثر تفصيلاً. عند تفعيل هذا الإعداد، لا يتم الإبلاغ عن كل تفاعل، ولكن في كل مرة يكون فيها تفاعل أبطأ من أي تفاعل سابق، يتم الإبلاغ عنه.

جرِّب إضافة الخيار إلى النص البرمجي والتفاعل مع الصفحة مرة أخرى:

<script type="module">
  import {onINP} from './node_modules/web-vitals/dist/web-vitals.attribution.js';

  onINP(console.log, {reportAllChanges: true});
</script>

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

لقطة شاشة لوحدة تحكّم أدوات مطوّري البرامج تمت طباعة رسائل مقياس INP عليها بنجاح

5- ما الذي تتضمّنه الإحالة؟

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

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

انقر على نعم لقبول ملفات تعريف الارتباط (إصدار تجريبي) والاطّلاع على بيانات INP المسجّلة الآن في وحدة تحكّم أدوات مطوّري البرامج.

عنصر بيانات مقياس INP المسجَّل في وحدة تحكّم أدوات مطوّري البرامج

تتوفّر هذه المعلومات عالية المستوى في كلٍّ من الإصدارات العادية وإصدارات مؤشرات أداء الويب لتحديد المصدر:

{
  name: 'INP',
  value: 344,
  rating: 'needs-improvement',
  entries: [...],
  id: 'v4-1715732159298-8028729544485',
  navigationType: 'reload',
  attribution: {...},
}

المدة الزمنية التي تبدأ من وقت نقر المستخدم إلى سرعة عرض الصفحة التالية كانت 344 مللي ثانية - "بحاجة إلى تحسين" مدى استجابة الصفحة لتفاعلات المستخدم (INP) تحتوي مصفوفة entries على جميع قيم PerformanceEntry المرتبطة بهذا التفاعل، وفي هذه الحالة، حدث نقرة واحدة فقط.

لمعرفة ما يحدث خلال هذه الفترة، يهمّنا كثيرًا استخدام السمة attribution. لإنشاء بيانات تحديد المصدر، يعثر web-vitals على إطار الصور المتحركة الطويلة (LoAF) الذي يتداخل مع حدث النقرة. يمكن لـ LoAF بعد ذلك تقديم بيانات تفصيلية عن الوقت المُستغرق خلال هذا الإطار، بدءًا من النصوص البرمجية التي تم تشغيلها إلى الوقت المُستغرق في معاودة الاتصال والنمط والتنسيق requestAnimationFrame.

وسِّع السمة attribution للاطّلاع على مزيد من المعلومات. البيانات أكثر ثراءً.

attribution: {
  interactionTargetElement: Element,
  interactionTarget: '#confirm',
  interactionType: 'pointer',

  inputDelay: 27,
  processingDuration: 295.6,
  presentationDelay: 21.4,

  processedEventEntries: [...],
  longAnimationFrameEntries: [...],
}

أولاً، هناك معلومات عن العناصر التي تم التفاعل معها:

  • interactionTargetElement: مرجع مباشر للعنصر الذي تم التفاعل معه (إذا لم تتم إزالة العنصر من DOM)
  • interactionTarget: أداة اختيار للعثور على العنصر داخل الصفحة

بعد ذلك، يتم تقسيم التوقيت بطريقة عالية المستوى:

  • inputDelay: الوقت بين بدء المستخدم التفاعل (على سبيل المثال، النقر على الماوس) ووقت بدء تشغيل أداة معالجة الحدث لذلك التفاعل في هذه الحالة، كان تأخير الإدخال حوالي 27 مللي ثانية فقط، حتى مع تشغيل تقييد وحدة المعالجة المركزية.
  • processingDuration: الوقت الذي تستغرقه أدوات معالجة الأحداث حتى الانتهاء غالبًا ما ستتضمّن الصفحات العديد من المستمعين لحدث واحد (مثل pointerdown وpointerup وclick). إذا تم تشغيلها جميعًا في نفس إطار الرسوم المتحركة، فسيتم دمجها معًا في هذا الوقت. في هذه الحالة، تستغرق مدة المعالجة 295.6 مللي ثانية، وهي الجزء الأكبر من وقت INP.
  • presentationDelay: الوقت من وقت اكتمال أدوات معالجة الحدث إلى وقت انتهاء المتصفّح من عرض الإطار التالي في هذه الحالة، 21.4 مللي ثانية.

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

من خلال التعمّق أكثر، يحتوي processedEventEntries على خمسة أحداث، بدلاً من الحدث الفردي في مصفوفة entries INP ذات المستوى الأعلى. ما الفارق؟

processedEventEntries: [
  {
    name: 'mouseover',
    entryType: 'event',
    startTime: 1801.6,
    duration: 344,
    processingStart: 1825.3,
    processingEnd: 1825.3,
    cancelable: true
  },
  {
    name: 'mousedown',
    entryType: 'event',
    startTime: 1801.6,
    duration: 344,
    processingStart: 1825.3,
    processingEnd: 1825.3,
    cancelable: true
  },
  {name: 'mousedown', ...},
  {name: 'mouseup', ...},
  {name: 'click', ...},
],

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

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

longAnimationFrameEntries

توسيع إدخال LoAF:

longAnimationFrameEntries: [{
  name: 'long-animation-frame',
  startTime: 1823,
  duration: 319,

  renderStart: 2139.5,
  styleAndLayoutStart: 2139.7,
  firstUIEventTimestamp: 1801.6,
  blockingDuration: 268,

  scripts: [{...}]
}],

هناك عدد من القيم المفيدة هنا، مثل توضيح مقدار الوقت المستغرق في التصميم. يمكنك الاطّلاع على مزيد من التفاصيل حول هذه السمات في مقالة Long Animation Frames API نهتم حاليًا بشكل أساسي بالسمة scripts، التي تحتوي على إدخالات تقدّم تفاصيل عن النصوص البرمجية المسؤولة عن الإطار الطويل الأمد:

scripts: [{
  name: 'script',
  invoker: 'BUTTON#confirm.onclick',
  invokerType: 'event-listener',

  startTime: 1828.6,
  executionStart: 1828.6,
  duration: 294,

  sourceURL: 'http://localhost:8080/third-party/cmp.js',
  sourceFunctionName: '',
  sourceCharPosition: 1144
}]

في هذه الحالة، يمكننا معرفة الوقت الذي تم قضاؤه بشكل أساسي في event-listener واحد، وتم استدعاءه في BUTTON#confirm.onclick. يمكننا حتى رؤية عنوان URL لمصدر النص البرمجي وموضع الحرف حيث تم تعريف الدالة!

طعام سفري

ما الذي يمكن تحديده بشأن هذه الحالة من بيانات تحديد المصدر هذه؟

  • تم بدء التفاعل من خلال نقرة على العنصر button#confirm (من attribution.interactionTarget والسمة invoker في أحد عناصر تحديد مصدر النص البرمجي).
  • تم قضاء الوقت في تنفيذ أدوات معالجة الأحداث بشكل أساسي (من attribution.processingDuration مقارنةً بالمقياس الإجمالي value).
  • يبدأ رمز أداة معالجة الأحداث البطيئة من أداة استماع للنقرة تم تحديدها في third-party/cmp.js (من scripts.sourceURL).

وهذه بيانات كافية لمعرفة الجوانب التي نحتاج إلى تحسينها.

6- أدوات معالجة الأحداث المتعددة

أعِد تحميل الصفحة كي تصبح وحدة التحكّم في "أدوات مطوري البرامج" واضحة ولم يعُد تفاعل الموافقة على ملفات تعريف الارتباط أطول مدة تفاعل.

ابدأ الكتابة في مربّع البحث. ماذا تعرض بيانات تحديد المصدر؟ ما الذي يحدث في رأيك؟

بيانات تحديد المصدر

أولاً، فحص عالي المستوى لمثال واحد على اختبار العرض التوضيحي:

{
  name: 'INP',
  value: 1072,
  rating: 'poor',
  attribution: {
    interactionTargetElement: Element,
    interactionTarget: '#search-terms',
    interactionType: 'keyboard',

    inputDelay: 3.3,
    processingDuration: 1060.6,
    presentationDelay: 8.1,

    processedEventEntries: [...],
    longAnimationFrameEntries: [...],
  }
}

وهو قيمة INP رديئة (عند تفعيل تقييد وحدة المعالجة المركزية) نتيجة تفاعل لوحة المفاتيح مع العنصر input#search-terms. قضى معظم الوقت في مدة المعالجة، أي 1061 مللي ثانية من إجمالي 1072 ملّي ثانية.

ومع ذلك، تُعد الإدخالات scripts أكثر إثارة للاهتمام.

تقسيم التصميم

يقدّم لنا الإدخال الأول في مصفوفة scripts بعض السياقات القيمة:

scripts: [{
  name: 'script',
  invoker: 'BUTTON#confirm.onclick',
  invokerType: 'event-listener',

  startTime: 4875.6,
  executionStart: 4875.6,
  duration: 497,
  forcedStyleAndLayoutDuration: 388,

  sourceURL: 'http://localhost:8080/js/index.js',
  sourceFunctionName: 'handleSearch',
  sourceCharPosition: 940
},
...]

تحدث معظم مدة المعالجة أثناء تنفيذ النص البرمجي هذا، وهو مستمع input (المُدعي هو INPUT#search-terms.oninput). يتم توفير اسم الدالة (handleSearch)، وكذلك موضع الأحرف داخل ملف المصدر index.js.

ومع ذلك، هناك موقع جديد: forcedStyleAndLayoutDuration. كان هذا هو الوقت المستغرَق في استدعاء هذا النص البرمجي، حيث تم إجبار المتصفّح على إرسال الصفحة. بعبارة أخرى، قضى 78٪ من الوقت - 388 مللي ثانية من 497 - في تنفيذ مستمع الحدث هذا بالفعل في تفكيك التخطيط.

يجب أن يكون هذا الأمر أولوية قصوى لإصلاحها.

أدوات معالجة الأحداث المتكررة

منفردًا، لا يوجد شيء رائع حقًا في الإدخالين التاليين للنص البرمجي:

scripts: [...,
{
  name: 'script',
  invoker: '#document.onkeyup',
  invokerType: 'event-listener',

  startTime: 5375.3,
  executionStart: 5375.3,
  duration: 124,

  sourceURL: 'http://localhost:8080/js/index.js',
  sourceFunctionName: '',
  sourceCharPosition: 1526,
},
{
  name: 'script',
  invoker: '#document.onkeyup',
  invokerType: 'event-listener',

  startTime: 5673.9,
  executionStart: 5673.9,
  duration: 95,

  sourceURL: 'http://localhost:8080/js/index.js',
  sourceFunctionName: '',
  sourceCharPosition: 1526
}]

كلا الإدخالين يمثلان أدوات معالجة الأحداث keyup، ويتم تنفيذهما الواحد تلو الآخر مباشرةً. تُعد أدوات معالجة البيانات دوال مجهولة (وبالتالي لا يتم الإبلاغ عن أي شيء في السمة sourceFunctionName)، ولكن لا يزال لدينا ملف المصدر وموضع الحرف، حتى نتمكن من العثور على مكان الرمز.

والمثير للدهشة هو أن كلاهما من الملف المصدر وموضع الحرف نفسهما.

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

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

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

7. مهلة الإدخال

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

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

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

  • انقر على شعار الحلزون لبدء الصورة المتحركة.
  • يتم تشغيل مهام JavaScript عندما يكون الحلزون في الجزء السفلي من الارتداد. حاوِل التفاعل مع الصفحة بالقرب من أسفل مرة الارتداد قدر الإمكان واطّلِع على مستوى INP الذي يمكنك تشغيله.

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

في العديد من الصفحات، لن يكون عمل سلسلة التعليمات الرئيسية مكثّفًا على هذا النحو، ولكن هذا مثال جيد لمعرفة كيف يمكن التعرّف عليه في بيانات إحالة INP.

في ما يلي مثال على الإحالة من التركيز على مربّع البحث فقط أثناء ارتداد الحلزون:

{
  name: 'INP',
  value: 728,
  rating: 'poor',

  attribution: {
    interactionTargetElement: Element,
    interactionTarget: '#search-terms',
    interactionType: 'pointer',

    inputDelay: 702.3,
    processingDuration: 4.9,
    presentationDelay: 20.8,

    longAnimationFrameEntries: [{
      name: 'long-animation-frame',
      startTime: 2064.8,
      duration: 790,

      renderStart: 2065,
      styleAndLayoutStart: 2854.2,
      firstUIEventTimestamp: 0,
      blockingDuration: 740,

      scripts: [{...}]
    }]
  }
}

وكما هو متوقَّع، يتم تنفيذ أدوات معالجة الأحداث بسرعة، ما أظهرت مدة معالجة تبلغ 4.9 مللي ثانية، وتم استهلاك الغالبية العظمى من التفاعل الضعيف أثناء مهلة الإدخال، ما شغَّل 702.3 مللي ثانية من إجمالي 728.

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

تتوفر إدخالات نص LoAF هنا لحفظ اليوم:

scripts: [{
  name: 'script',
  invoker: 'SPAN.onanimationiteration',
  invokerType: 'event-listener',

  startTime: 2065,
  executionStart: 2065,
  duration: 788,

  sourceURL: 'http://localhost:8080/js/index.js',
  sourceFunctionName: 'cryptodaphneCoinHandler',
  sourceCharPosition: 1831
}]

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

من خلال ذلك، يمكننا معرفة الطريقة التي أدّت إلى تأخير عملية معالجة التفاعل (من قِبل مستمع animationiteration)، ومعرفة الوظيفة التي كانت مسؤولة عن الفهرسة، ومكان هذه الوظيفة في ملفات المصدر.

8. مهلة العرض التقديمي: عندما لا تظهر النتائج المترتبة على التحديث

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

أعِد تحميل الصفحة لإعادة ضبط قيمة INP مرة أخرى، ثم افتح قائمة الخطوط الثلاثة. هناك مشكلة محددة عند فتحها.

كيف يبدو هذا؟

{
  name: 'INP',
  value: 376,
  rating: 'needs-improvement',
  delta: 352,

  attribution: {
    interactionTarget: '#sidenav-button>svg',
    interactionType: 'pointer',

    inputDelay: 12.8,
    processingDuration: 14.7,
    presentationDelay: 348.5,

    longAnimationFrameEntries: [{
      name: 'long-animation-frame',
      startTime: 651,
      duration: 365,

      renderStart: 673.2,
      styleAndLayoutStart: 1004.3,
      firstUIEventTimestamp: 138.6,
      blockingDuration: 315,

      scripts: [{...}]
    }]
  }
}

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

scripts: [{
  entryType: 'script',
  invoker: 'FrameRequestCallback',
  invokerType: 'user-callback',

  startTime: 673.8,
  executionStart: 673.8,
  duration: 330,

  sourceURL: 'http://localhost:8080/js/side-nav.js',
  sourceFunctionName: '',
  sourceCharPosition: 1193,
}]

بالاستناد إلى الإدخال الفردي في المصفوفة scripts، يظهر لنا الوقت المستغرَق في user-callback من FrameRequestCallback. هذه المرة يحدث تأخر العرض بسبب معاودة الاتصال requestAnimationFrame.

9. الخاتمة

تجميع بيانات الحقول

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

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

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

وبالمثل، قد تحتوي الإدخالات scripts على تجزئات مستندة إلى الملفات في مسارات sourceURL تجعل من الصعب دمجها، ولكن يمكنك إزالة علامات التجزئة استنادًا إلى عملية التصميم المعروفة قبل إرسال إشارة للبيانات.

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

الإحالة في كل مكان

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

أصبحت جاهزًا الآن لاستخدام بيانات إحالة INP على أي موقع إلكتروني.

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

const script = document.createElement('script');
script.src = 'https://unpkg.com/web-vitals@4/dist/web-vitals.attribution.iife.js';
script.onload = function () {
  webVitals.onINP(console.log, {reportAllChanges: true});
};
document.head.appendChild(script);

مزيد من المعلومات