قياس الأداء في تطبيقات Next.js
تتيح لك الأداة Next.js Analytics تحليل وقياس أداء الصفحات مستخدمًا مؤشرات مختلفة. فقد تبدأ بتجميع نقاط التجربة الواقعية Real Experience Score دون إعدادات عند النشر على Vercel، كما يمكنك دعم Next.js Analytics إن اخترت الاستضافة الذاتية.
تشرح الأقسام التالية في هذه الصفحة من التوثيق الطبقات المدمجة التي يستخدمها Next.js Analytics.
استخدام المؤشرات التي تناسبك
عليك إولًا إنشاء مكوّن App
مخصص وتعرّف داخله الدالة reportWebVitals
:
// pages/_app.js
export function reportWebVitals(metric) {
console.log(metric)
}
function MyApp({ Component, pageProps }) {
return <Component {...pageProps} />
}
export default MyApp
تُستدعى هذه الدالة عندما تُحسب القيمة النهائية لأي مؤشر في الصفحة، وبإمكانك عندها عرض النتيجة على الطرفية إو إرسالها إلى وصلة خاصة لتخزينها. يتكوّن الكائن metric
الذي يُعاد إلى الدالة من خاصيات عدة هي:
id
: مُعرِّف فريد للمؤشر في سياق الحمل الذي تعرضه الصفحة الحالية.name
: اسم المؤشر.startTime
: زمن التسجيل الأول لقيمة الأداء بالميلي ثانية إن أمكن.value
: قيمة أو فترة زمنية لمؤشر الأداء.label
: نوع المؤشرweb-vital
(مؤشرات ويب الحيوية) أوcustom
(مؤشر مخصص)
مؤشرات الويب الحيوية Web Vitals
مؤشرات ويب الحيوية هي مجموعة من المؤشرات المفيدة التي تهدف إلى تقييم تجربة المستخدم لصفحة ويب، ويمكنك قياس جميع المؤشرات التالية:
- زمن وصول البايت الأول Time to First Byte واختصارًا TTFB
- أول محتوى مرئي في نافذة العرض First Contentful Paint واختصارًا FCP
- أضخم محتوى مرئي في نافذة العرض Largest Contentful Paint ,واختصارًا LCP
- زمن الاستجابة لأول تفاعل مع الصفحة First Input Delay واختصارًا FID
- انزياح الهكيل التراكمي Cumulative Layout Shift واختصارًا CLS
بإمكانك التعامل مع جميع المؤشرات السابقة من خلال العنوان web-vital
للكائن metric
:
export function reportWebVitals(metric) {
if (metric.label === 'web-vital') {
console.log(metric) // تُعرض المؤشرات التالية
// ({ id, name, startTime, value, label })
// على الطرفية
}
}
وهنالك أيضًا خيارات لمعالجة كل مؤشر على حدى:
export function reportWebVitals(metric) {
switch (metric.name) {
case 'FCP':
// FCP يعالج نتيجة
break
case 'LCP':
// LCP يعالج نتيجة
break
case 'CLS':
// CLS يعالج نتيجة
break
case 'FID':
// FID يعالج نتيجة
break
case 'TTFB':
// TTFB يعالج نتيجة
break
default:
break
}
}
تستخدم المكتبة web-vitals التي يؤمنها طرف آخر لقياس هذه المؤشرات. وتعتمد توافقية المتصفح على المؤشر الذي يقيسه، لذلك عليك الاطلاع على المتصفحات التي تدعمها هذه الأداة.
المؤشرات المخصصة Custom metrics
إضافة إلى المؤشرات الحيوية السابقة، ستجد بعض المؤشرات المخصصة التي تقيس الزمن الذي تستغرقه الصفحة لكي تُرطَّب وتصيَّر:
Next.js-hydration
: الفترة الزمنية التي تستغرقها صفحة بين بداية ونهاية الترطيب (بالميلي ثانية).Next.js-route-change-to-render
: الفترة الزمنية التي تستغرقها صفحة ليبدأ تصييرها بعد تغيّر الوجهة (أو المسار).Next.js-render
: الفترة الزمنية التي تستغرقها صفحة لينتهي تصييرها بعد تغيّر الوجهة (أو المسار).
بإمكانك التعامل مع جميع نتائج هذه المؤشرات باستخدام العنوان custom
للكائن metric
:
export function reportWebVitals(metric) {
if (metric.label === 'custom') {
console.log(metric) // تُعرض المؤشرات التالية
// ({ id, name, startTime, value, label })
// على الطرفية
}
}
وهنالك أيضًا خيار لمعالجة كل مؤشر على حدى:
export function reportWebVitals(metric) {
switch (metric.name) {
case 'Next.js-hydration':
// تعالج نتيجة الترطيب
break
case 'Next.js-route-change-to-render':
// تعالج نتيجة زمن انتهاء التصيير عند تغير الوجهة
break
case 'Next.js-render':
// تعالج زمن بداية التصيير عند تغير الوجهة
break
default:
break
}
}
تعمل هذه المؤشرات في جميع المتصفحات التي تدعم الواجهة البرمجية User Timing.
إرسال البيانات إلى الأداة analytics
بإمكانك إرسال بيانات أي مؤشر إلى الوصلة الخاصة بالأداة analytics لقياس وتتبع الأداء الفعلي للمستخدم على موقعك من خلال دالة توصيل. إليك مثالًا:
export function reportWebVitals(metric) {
const body = JSON.stringify(metric)
const url = 'https://example.com/analytics'
//إن كان متاحًا `navigator.sendBeacon()` استخدم
//`fetch()` وإلا تراجع إلى
if (navigator.sendBeacon) {
navigator.sendBeacon(url, body)
} else {
fetch(url, { body, method: 'POST', keepalive: true })
}
}
ملاحظة: إن كنت تستخدم Google Analytics، فستسمح لك قيمة id
أن تبني توزعًا يدويًا للمؤشرات لتحسب نسبًا مئوية وغيرها إن شئت.
export function reportWebVitals({ id, name, label, value }) {
// كما في المثال التالي Google Analytics إن هيأت `window.gtag` استخدم
// https://github.com/vercel/next.js/blob/canary/examples/with-google-analytics/pages/_app.js
window.gtag('event', name, {
event_category:
label === 'web-vital' ? 'Web Vitals' : 'Next.js custom metric',
value: Math.round(name === 'CLS' ? value * 1000 : value), // يجب أن تكون القيم صحيحة
event_label: id, //فريد بالنسبة للحمل الحالي للصفحة id المعرف
non_interaction: true, //bounce rate تحاشى التاثير على معدل النشاط
})
}
للمزيد، انظر هذه الصفحة.
استكشاف ما يؤثر على مؤشرات الويب الحيوية
عند استكشاف المشاكل المتعلقة بمؤشرات الويب الحيوية وفحصها، قد نحتاج عادةً إلى أي معلومة تفيدنا في تحديد سبب المشكلة مثلًا قد نحتاج في مؤشر انزياح الهيكل التراكمي CLS إلى معرفة أول عنصر منزاح عندما حصلت مشكلة الانزياح الهيكل أو مثلًا قد نحتاج في مؤشر أضخم محتوى مرئي LCP إلى تحديد العنصر المسؤول عن خلل هذا المؤشر فإن كان العنصر صورةٌ فسيساعدنا معرفة تفاصيله ورابط الصورة تلك إلى تحديد الصورة بالضبط والرجوع إليها وتحسينها.
تعرف عملية تحديد المساهم الأكبر في مشاكل الويب الحيوية باسم "الإرجاع" attribution أي إرجاع المشكلة إلى مسببها، وتساعدنا هذه العملية في معرفة تفاصيل أوسع وأدق عن المشكلة مثل:
هذه العملية معطلة افتراضيًا في Next.js ويمكنك تفعيلها لكل مؤشر من ملف next.config.js بالشكل التالي:
// next.config.js
experimental: {
webVitalsAttribution: ['CLS', 'LCP']
}
القيم الصالحة لتمريرها إلى webVitalsAttribution
هي كل مؤشرات الويب الحيوية web-vitals
المحددة في النوع NextWebVitalsMetric
.
استخدام TypeScript
يمكنك استخدام النوع المدمج NextWebVitalsMetric
في حال استخدمت TypeScript:
// pages/_app.tsx
import type { AppProps, NextWebVitalsMetric } from 'next/app'
function MyApp({ Component, pageProps }: AppProps) {
return <Component {...pageProps} />
}
export function reportWebVitals(metric: NextWebVitalsMetric) {
console.log(metric)
}
export default MyApp
المصادر
- الصفحة Measuring performance من توثيق Next.js الرسمي.