قياس مدى استجابة الصفحة لتفاعلات المستخدم (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 في أغلب الأحيان على الأجهزة الجوّالة، لذا بدِّل إلى محاكي العرض على الأجهزة الجوّالة.
  • إذا كنت تختبر على كمبيوتر مكتبي أو كمبيوتر محمول، من المرجّح أن يكون الأداء أفضل بكثير من الأداء على جهاز جوّال حقيقي. للحصول على نظرة أكثر واقعية على الأداء، انقر على رمز الترس في أعلى يسار لوحة الأداء، ثم اختَر إبطاء وحدة المعالجة المركزية (CPU) بمقدار 4 مرات.

لقطة شاشة للوحة "الأداء" في DevTools بجانب التطبيق، مع تحديد خيار إبطاء وحدة المعالجة المركزية بمقدار 4 مرات

4. تثبيت مكتبة web-vitals

web-vitals هي مكتبة JavaScript لقياس مقاييس Web Vitals التي يختبرها المستخدمون. يمكنك استخدام المكتبة لتسجيل هذه القيم، ثم إرسالها إلى نقطة نهاية خدمة إحصاءات لإجراء تحليل لاحق، وذلك لتحديد وقت حدوث التفاعلات البطيئة ومكان حدوثها.

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

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

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

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

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

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

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

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

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

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

5- ما هي المعلومات التي تتضمّنها عملية تحديد المصدر؟

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

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

انقر على نعم لقبول ملفات تعريف الارتباط (التجريبية)، وألقِ نظرة على بيانات INP التي تم تسجيلها الآن في وحدة تحكّم "أدوات المطوّرين".

كائن بيانات INP الذي تم تسجيله في &quot;وحدة تحكّم أدوات مطوّري البرامج&quot;

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

{
  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 على خمسة أحداث، على عكس الحدث الفردي في مصفوفة INP entries ذات المستوى الأعلى. ما الفرق بينهما؟

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 ملي ثانية من إجمالي مدة INP البالغة 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);

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