ويؤدي ضعف الاستجابة للتفاعلات إلى انطباع سيئ بأنّ الصفحة بطيئة أو حتى معطّلة تمامًا. "مدى استجابة الصفحة لتفاعلات المستخدم" (INP) هو مقياس يستند إلى Event Timing API. ويقيس أسوأ تفاعل (باستثناء بعض القيم الشاذة) كمقياس لسرعة استجابة الصفحة.
قد يكون تحديد الأسباب الأساسية لعدم استجابة صفحة الويب أمرًا صعبًا، خاصةً أنّه يعتمد على تفاعلات المستخدمين والظروف البيئية، مثل إمكانات الجهاز وحالة الشبكة. وهذا يجعل تشخيصها أكثر صعوبة مقارنةً بسيناريو أكثر قابلية للتكرار والتوقّع، مثل تحميل الصفحة. لا تكرّر البيانات الاختبارية سوى مجموعة فرعية صغيرة من سيناريوهات المستخدمين الحقيقيين، لذا من الضروري قياس أسباب بطء مقياس INP في المجال.
تتيح Event Timing API تقسيم مدة INP إلى ثلاثة أجزاء فرعية: "تأخير الإدخال" (المعالجة التي تحدث عند حدوث التفاعل) و"مدة المعالجة" (التأخيرات الناتجة عن التفاعل مباشرةً) و"تأخير العرض" (التأخيرات الناتجة عن عرض الإطار التالي بعد التفاعل). يساعد ذلك في تحديد ما إذا كانت المشكلة تكمن في رمز آخر أو في رمز JavaScript الخاص بالتفاعل أو في معالجة المتصفّح لتعديلات العرض على التوالي بدلاً من الانتقال مباشرةً إلى رمز التفاعل.
يمكن جمع المزيد من الإحصاءات حول JavaScript وإعادة احتساب الأنماط وعمل التنسيق الذي يؤخر التفاعل. إنّ تتبُّع الأداء الكامل باستخدام JS Self-Profiling API هو حلّ ثقيل من المرجّح أن يتسبّب في مشاكل في الأداء. واجهة برمجة تطبيقات صور متحركة يستغرق عرضها وقتًا طويلاً هي واجهة برمجة تطبيقات بسيطة يمكن استخدامها في المجال لتحديد JavaScript البطيء والتمييز بين إعادة احتساب الأنماط وتكاليف التنسيق أثناء تفاعلات مدى استجابة الصفحة لتفاعلات المستخدم (INP):
- النمط والتنسيق المفروضان على مستوى النص البرمجي (
forcedStyleDurationوforcedLayoutDuration): يعرض هذا المقياس عمليات إعادة احتساب الأنماط المتزامنة (مثل استدعاءgetComputedStyle()بعد تغييرات نموذج العناصر في المستند) والتنسيقات/عمليات إعادة التدفق المفروضة (مثل قراءةgetBoundingClientRect()أوoffsetWidthبعد التغييرات) داخل نص برمجي قيد التشغيل أثناء مهلة الإدخال أو مدة المعالجة. - نمط العرض والتنسيق على مستوى اللقطة (
styleDurationوlayoutDuration): يعرض الوقت المستغرَق في إعادة احتساب الأنماط مقابل تعديل التنسيق أثناء تعديل عرض اللقطة، ما يساعد في تفسير ارتفاع تأخير العرض.
من المهم التمييز بين إعادة احتساب الأنماط والتصميم لأنّ لكل منهما أسبابًا أساسية وحلولاً مختلفة: تشير مدة الأنماط العالية إلى مطابقة أدوات اختيار CSS المكلفة أو إبطال الأنماط على نطاق واسع (يتم حلّها من خلال تبسيط أدوات اختيار لغة CSS أو تقليل نطاق القواعد)، بينما تشير مدة التصميم العالية إلى عمليات احتساب هندسية مكلفة أو الاحتدام المتزامن للتصميم (يتم حلّها من خلال تجميع عمليات قراءة DOM قبل الكتابة أو تبسيط بنية DOM أو استخدام احتواء CSS).
كيفية الإعداد
إنّ احتساب مقياس INP من واجهة Event Timing API الأولية أمر معقّد وله عدة جوانب دقيقة. ننصحك باستخدام أداة أو مكتبة RUM لجمع هذه البيانات.
web-vitals هي مكتبة مفتوحة المصدر من Google تحسب مؤشرات Core Web Vitals، بما في ذلك مقياس INP، وتتضمّن أيضًا أجزاء فرعية وبيانات صور متحركة يستغرق عرضها وقتًا طويلاً لتفاعل INP.
الحصول على معلومات تحديد المصدر لتفاعلات INP باستخدام مكتبة web-vitals
مكتبة web-vitals هي مكتبة صغيرة تُستخدَم لقياس مؤشرات Core Web Vitals ومقاييس الأداء الأخرى. يمكن استخدام الدالة onINP() لتحديد أبطأ تفاعل، وهي تتضمّن معلومات عن الأجزاء الفرعية لمقياس INP والنصوص البرمجية التي تم تنفيذها أثناء التفاعل ومدد الأنماط والتنسيقات باستخدام Long Animation Frames API.
// Use the attribution build to get Long Animation Frame data
// alongside the INP metric value.
import { onINP } from 'web-vitals/attribution';
onINP((metric) => {
const { attribution } = metric;
const longestScript = attribution.longestScript;
// Sum rendering-phase style and layout durations across all LoAF entries
// intersecting the INP interaction (primarily explains presentationDelay).
let renderStyleDuration = 0;
let renderLayoutDuration = 0;
for (const entry of attribution.longAnimationFrameEntries) {
renderStyleDuration += entry.styleDuration ?? 0;
renderLayoutDuration += entry.layoutDuration ?? 0;
}
// Beacon script, style, and layout attribution for the INP interaction,
// so you can identify the root cause in production.
navigator.sendBeacon(
'/analytics',
JSON.stringify({
name: 'INP',
value: metric.value,
// These fields give the INP subparts:
inputDelay: attribution.inputDelay,
presentationDelay: attribution.presentationDelay,
processingDuration: attribution.processingDuration,
interactionTarget: attribution.interactionTarget,
// These fields identify which script function was responsible
// for the longest processing during the INP interaction.
invokerType: longestScript?.entry?.invokerType,
sourceURL: longestScript?.entry?.sourceURL,
sourceFunctionName: longestScript?.entry?.sourceFunctionName,
sourceCharPosition: longestScript?.entry?.sourceCharPosition,
// subpart indicates which phase (input delay, processing, or
// presentation delay) the longest script overlapped with most.
subpart: longestScript?.subpart,
intersectingDuration: longestScript?.intersectingDuration,
// Synchronous style and layout work forced inside the longest script
// (with forcedStyleAndLayoutDuration as a combined fallback):
forcedStyleDuration: longestScript?.entry?.forcedStyleDuration,
forcedLayoutDuration: longestScript?.entry?.forcedLayoutDuration,
forcedStyleAndLayoutDuration: longestScript?.entry?.forcedStyleAndLayoutDuration,
// Rendering-phase style and layout work across the interaction's frames
// (with totalStyleAndLayoutDuration as a combined fallback):
renderStyleDuration,
renderLayoutDuration,
totalStyleAndLayoutDuration: attribution.totalStyleAndLayoutDuration
})
);
});
أفضل الممارسات
- يجب استخدام الأجزاء الفرعية لمقياس INP في البداية لتحديد ما إذا كان التأخير ناتجًا عن تشغيل JavaScript (تأخير الإدخال)، أو معالِجات أحداث JavaScript للتفاعل (مدة المعالجة)، أو العرض اللاحق (تأخير العرض).
- يجب محاولة تحديد أكبر ملف JavaScript يحظر العرض كتفاصيل إضافية، خاصةً في ما يتعلّق بمهلة الاستجابة ومدة المعالجة.
- يجب التمييز بين إعادة احتساب الأنماط (
styleDurationوforcedStyleDuration) والتنسيق (layoutDurationوforcedLayoutDuration) عند تشخيص مدة المعالجة العالية أو تأخير العرض: تشير أوقات الأنماط العالية إلى أدوات اختيار لغة CSS المكلفة أو عمليات الإبطال الواسعة، بينما تشير أوقات التنسيق العالية إلى ازدحام في هندسة DOM أو تكرار التنسيق المتزامن. - يُفضَّل استخدام واجهة Long Animation Frames API لتقديم هذه التفاصيل الإضافية بدلاً من البدائل، مثل واجهة JS Self-Profiling API، التي تستهلك قدرًا أكبر من موارد وقت التشغيل.
- يجب استخدام مكتبة
web-vitalsفي حال عدم توفّر حلّ آخر لمراقبة المستخدمين الحقيقيين. ويمكنها تحديد تفاعل INP وتتضمّن معلومات حول الأجزاء الفرعية والنصوص البرمجية التي تم تنفيذها أثناء التفاعل (باستخدام Long Animation Frames API). - يجب إرسال المعلومات المطلوبة إلى خدمة إحصاءات بدلاً من تسجيلها محليًا فقط.
توافق المتصفّح واستراتيجيات الاحتياط
تتوفّر واجهة Event Timing API في معظم المتصفّحات الحديثة، وهي ضرورية لاحتساب مقياس INP وأجزائه الفرعية. ولا يمكن قياس مقياس INP في المتصفّحات التي لا تتوافق مع واجهة برمجة التطبيقات هذه.
توفّر واجهة برمجة التطبيقات Long Animation Frames تفاصيل إضافية اختيارية. ويمكن استخدامها بأمان بدون إجراءات احتياطية. وفي معظم الحالات، ستنطبق فرص تحسين الأداء التي تحدّدها على المتصفّحات الأخرى أيضًا.
إذا كان هدفك الأساسي يتيح استخدام واجهة Long Animation Frames API (long-animation-frames) ولكنّه لا يتيح استخدام سمات منفصلة لمدة الأنماط والتنسيقات (styleDuration وlayoutDuration في PerformanceLongAnimationFrameTiming، أو forcedStyleDuration وforcedLayoutDuration في PerformanceScriptTiming)، يمكنك الرجوع إلى توقيتات الأنماط والتنسيقات المجمّعة:
- استخدِم
script.forcedStyleAndLayoutDurationفيPerformanceScriptTimingلتنفيذ مهام التنسيق والتصميم المتزامنة داخل النصوص البرمجية. - استخدِم
metric.attribution.totalStyleAndLayoutDurationفيweb-vitals/attribution(أو احسب(entry.paintTime || entry.startTime + entry.duration) - entry.styleAndLayoutStartفي كل إدخالPerformanceLongAnimationFrameTiming) لدمج عمل النمط والتنسيق.