سلام! 😃 امروز می‌خواهیم در مورد یکی از مفاهیم مهم در تجربه کاربری وب صحبت کنیم: Interaction to Next Paint (INP). این metric (شاخص) جدید که برای سنجش سرعت واکنش صفحه به تعاملات کاربر طراحی شده است از مارس ۲۰۲۴ جایگزین شاخص قدیمی First Input Delay (FID) شده است.

INP چیست؟

INP (Interaction to Next Paint) یک معیار عملکردی است که میزان پاسخ‌گویی واقعی صفحه وب به تعاملات کاربر را می‌سنجد. این شاخص، فاصله زمانی بین لحظه‌ای که کاربر با صفحه تعامل می‌کند (مثلاً کلیک می‌کند، ضربه می‌زند یا کلیدی را فشار می‌دهد) و لحظه‌ای که اولین واکنش بصری مرتبط در صفحه ظاهر می‌شود را اندازه‌گیری می‌کند. منظور از واکنش بصری می‌تواند چیزهایی مثل باز شدن یک منو، نمایش پیام موفقیت، تغییر وضعیت یک دکمه یا هر تغییری باشد که نشان دهد صفحه به فرمان کاربر پاسخ داده است.

به زبان ساده، INP بررسی می‌کند که پس از یک تعامل، چقدر طول می‌کشد تا مرورگر فریم جدیدی را نمایش دهد که نتیجه آن تعامل را به کاربر نشان دهد. هر چقدر این زمان کمتر باشد، حس پاسخ‌گویی سریع‌تر و روان‌تر به کاربر منتقل می‌شود. اما اگر این زمان زیاد باشد (مثلاً بالای چند صد میلی‌ثانیه)، کاربر ممکن است تصور کند سایت کند است یا اصلاً فرمان او را دریافت نکرده.

چرا INP معرفی شد؟

دلیل اصلی معرفی INP پوشش نقاط ضعفی بود که FID داشت. FID فقط تاخیر اولین ورودی کاربر در صفحه را اندازه‌گیری می‌کرد و آن هم فقط برای اولین تعامل پس از لود صفحه. این یعنی اگر اولین کلیک کاربر سریع بود اما سایر تعاملات بعدی کند بودند، FID متوجه آن‌ها نمی‌شد.

در مقابل، INP تمام تعاملات کاربر در طول حضورش در صفحه را تحت نظر می‌گیرد و بدترین آن‌ها را به عنوان نماینده تجربه کاربر گزارش می‌کند. به همین دلیل INP یک دید جامع‌تر نسبت به تعامل‌پذیری کلی صفحه می‌دهد. طبق آمار کروم، ۹۰٪ زمان حضور کاربر در صفحه پس از بارگذاری اولیه است؛ بنابراین باید سرعت پاسخ‌گویی در کل این مدت سنجیده شود نه فقط اولین کلیک. این همان کاریست که INP انجام می‌دهد.

اهمیت INP در سئو چیست ؟

INP اکنون یکی از سه شاخص اصلی Core Web Vitals گوگل است (در کنار LCP و CLS) و مستقیماً روی رتبه‌بندی نتایج جستجو تاثیر می‌گذارد. اگر سایت شما INP کند (ضعیف) داشته باشد، می‌تواند سیگنال منفی به گوگل بدهد و بر SEO شما اثر منفی بگذارد. برعکس، INP سریع (خوب) نشان‌دهنده تجربه کاربری بهتر است که گوگل آن را در رتبه‌بندی لحاظ می‌کند. پس بهبود INP نه تنها کاربران راضی‌تری ایجاد می‌کند بلکه برای بهینه‌سازی موتور جستجو نیز مهم است. به قول یک متخصص: “اگر INP را بهینه نکنید، عملکرد سایت و رتبه آن در جستجو ممکن است آسیب ببیند.”

مقایسه FID و INP (تفاوت‌ها)

حالا که فهمیدیم INP چیست، بیایید مقایسه‌ای دقیق بین INP و FID داشته باشیم و ببینیم چه تفاوت‌هایی دارند و چرا INP جامع‌تر است. جدول زیر تفاوت‌های کلیدی این دو شاخص را نشان می‌دهد:

ویژگیFID (First Input Delay)INP (Interaction to Next Paint)
چه چیزی را می‌سنجدتأخیر اولین ورودی کاربر (تاخیر از کلیک تا شروع پردازش)واکنش‌پذیری کلی صفحه در طول عمر آن (بدترین تأخیر در بین همه تعاملات)
کدام تعاملات؟فقط اولین تعامل بعد از بارگذاری صفحههمه تعاملات کاربر (کلیک، تپ، کیبورد) در کل زمانی که کاربر در صفحه است
بخش‌های زمانیفقط Input Delay (تاخیر شروع پردازش اولین ایونت)مجموع سه بخش: Input Delay + Processing Time + Presentation Delay (برای هر تعامل – بعداً توضیح می‌دهیم)
زمان اندازه‌گیریعمدتاً مربوط به زمان لود اولیه صفحه (حس اولیه)در کل مدت کار با صفحه (چه در لحظه لود چه بعداً) هر زمانی که تعامل رخ دهد
نحوه ارزیابیفقط در داده‌های میدانی (Field) در دسترس بود؛ در ابزارهای لابراتوار از معیاری مثل TBT برای شبیه‌سازی استفاده می‌شد.هم در داده میدانی (کروم UX Report) سنجیده می‌شود، هم در شرایط آزمایشگاهی با شبیه‌سازی تعاملات (مثلاً DevTools) قابل اندازه‌گیری است.
تأثیر بر تجربهمحدود – اگر اولین تعامل سریع باشد، FID عالی می‌شود حتی اگر بقیه تعاملات کند باشند.جامع – حتی اگر یک تعامل خیلی کند در طول استفاده کاربر رخ دهد، INP آن را منعکس می‌کند. نشان‌دهنده بدترین تجربه کاربر در آن صفحه.

همان‌طور که می‌بینید، INP یک ارتقاء نسل بعدی برای سنجش تعامل‌پذیری است. FID بیشتر روی اولین برخورد کاربر تمرکز داشت و یک معیار “شروع بارگذاری” بود، در حالی که INP نشان‌دهنده تعامل‌پذیری کلی صفحه است. به این خاطر، INP معیار قابل اعتماد‌تری برای تشخیص صفحات کند از دید کاربر محسوب می‌شود. به عبارتی اگر صفحه‌ای INP خوبی داشته باشد، یعنی تقریباً تمام تعاملات کاربر در آن صفحه سریع و روان بوده‌اند که هدف نهایی ماست.

نحوه محاسبه INP (تشریح Input Delay, Processing, Presentation)

برای درک INP، باید بفهمیم وقتی کاربر با صفحه تعامل می‌کند چه اتفاقی می‌افتد. هر تعامل کاربر (مثلاً کلیک روی دکمه) یک چرخه حیات دارد که شامل سه بخش زمانی است:

  1. Input Delay (تاخیر ورودی): یا تأخیر ورودی، مدت‌زمانی است که از لحظه‌ای که کاربر کاری انجام می‌دهد (مثل کلیک روی یک دکمه) تا زمانی که مرورگر بتواند اولین واکنش به آن کار را اجرا کند، طول می‌کشد. اگر در این زمان، مرورگر درگیر کارهای دیگری باشد (مثلاً مشغول اجرای یک اسکریپت سنگین)، واکنش به ورودی کاربر به تأخیر می‌افتد. این همان زمانی است که کاربر منتظر می‌ماند تا پاسخی ببیند، و ما به آن Input Delay می‌گوییم.
  2. Processing Time (زمان پردازش): از لحظه شروع به اجرای event handler ها تا پایان اجرای همه کدهای مربوط به آن تعامل را شامل می‌شود. در این مدت مرورگر در حال پردازش جاوااسکریپت (یا هر منطق مرتبط با آن رویداد) است. اگر کد مربوط به کلیک خیلی طولانی یا سنگین باشد، این بخش زیاد می‌شود.
  3. Presentation Delay (تاخیر ارائه): فاصله از پایان پردازش event handler‌ها تا زمانی که فریم بعدی که شامل تغییرات ناشی از آن تعامل است روی صفحه نمایش داده شود. در این بخش، مرورگر ممکن است درگیر محاسبه styleها، Layout و رندر کردن تغییرات DOM باشد و سپس منتظر چرخه نقاشی بعدی (Paint) می‌ماند تا نتیجه را به کاربر نشان دهد. هرگونه سنگینی در رندر یا آپدیت DOM می‌تواند این بخش را طولانی‌تر کند.

برای روشن‌تر شدن موضوع، به نمودار زیر توجه کنید. این Timeline یک تعامل کاربر را نشان می‌دهد که چگونه این سه بخش پشت سر هم اتفاق می‌افتند:

inp - Input Delay, Processing, Presentation - inadramseo.com

نمودار زمانی یک تعامل کاربر: از شروع تعامل (Start of Interaction) تا نمایش فریم بعدی (Next frame painted). سه بخش اصلی شامل Input Delay (آبی)، Processing Time (سبز) و Presentation Delay (قرمز) مشخص شده‌اند.

همان‌طور که در نمودار بالا می‌بینید: کاربر یک تعامل را آغاز می‌کند؛ ممکن است کمی تاخیر ورودی باشد تا مرورگر واکنش نشان دهد (بخاطر مشغول بودن ترد اصلی)، سپس پردازش مربوط به رویداد انجام می‌شود (Processing)، و در پایان مرورگر خروجی را روی صفحه نقاشی (Paint) می‌کند. INP در واقع مدت زمان کل از شروع تعامل تا نقاشی فریم بعدی است که این سه بخش را شامل می‌شود. هر کدام از این بخش‌ها می‌توانند روی سرعت احساس‌شده توسط کاربر تأثیر بگذارند:

  • اگر Input Delay زیاد باشد، کاربر روی دکمه کلیک کرده ولی مدتی هیچ اتفاقی نمی‌افتد (احساس کندی اولیه).
  • اگر Processing طولانی باشد، ممکن است رابط کاربری حین پردازش “گیر” کند یا انیمیشن‌ها لگ بزنند.
  • اگر Presentation Delay زیاد باشد، نتیجه تعامل (مثلاً باز شدن منو یا اضافه شدن آیتم) با تأخیر قابل مشاهده است.

فرمول محاسبه INP:

برای هر تعامل کاربر، می‌توان INP همان تعامل را این‌طور در نظر گرفت: INPinteraction​=Input Delay+Processing Time+Presentation Delay


INP صفحه چیست ؟

مرورگر (مثلاً کروم) هنگام حضور کاربر در یک صفحه، زمان پاسخ‌دهی به تمام تعاملات کاربر مثل کلیک یا فشار کلید را ثبت می‌کند. برای هر تعامل، مرورگر مقدار Input Delay، Processing Time و Presentation Delay را محاسبه کرده و مجموع آن‌ها را به عنوان زمان پاسخ‌گویی آن تعامل خاص در نظر می‌گیرد. در نهایت، از بین تمام تعاملات رخ‌داده، کندترین تعامل (یعنی با بیشترین تأخیر) به‌عنوان INP نهایی آن بازدید ثبت می‌شود.

البته اگر تعداد زیادی تعامل رخ دهد، گوگل به‌صورت هوشمند چند مورد استثنایی و نادر را که بسیار کند هستند نادیده می‌گیرد تا تجربه کلی را بهتر بازتاب دهد.

وقتی این داده‌ها از هزاران بازدید توسط کاربران واقعی جمع می‌شود، گوگل از صدک ۷۵ (p75) برای ارزیابی نهایی استفاده می‌کند. یعنی اگر ۷۵٪ از کاربران تجربه پاسخ‌گویی خوبی داشته باشند، آن صفحه از نظر INP خوب ارزیابی می‌شود. این معیار در ابزارهایی مثل PageSpeed Insights و Search Console نیز به همین شکل لحاظ می‌شود.

آستانه‌های INP: چه امتیازهایی خوب، متوسط یا ضعیف است؟

گوگل برای تفسیر INP سه بازه کیفی تعریف کرده است: «خوب» (Good)، «نیاز به بهبود» (Needs Improvement) و «ضعیف» (Poor). این آستانه‌ها به شما می‌گویند INP صفحه‌تان در چه وضعیتی قرار دارد:

  • INP خوب (سبز): اگر INP صفحه ۲۰۰ میلی‌ثانیه یا کمتر باشد، آن را خوب (Good) در نظر می‌گیرند. چنین صفحاتی از نظر واکنش‌پذیری عالی هستند و تعاملات کاربر تقریباً فوری پاسخ داده می‌شوند (احساس روان بودن کامل).
  • INP متوسط (زرد – نیاز به بهبود): اگر INP صفحه بین ۲۰۰ تا ۵۰۰ میلی‌ثانیه باشد، در محدوده «نیاز به بهبود» قرار می‌گیرد. این صفحات بد نیستند اما جای کار دارند. کاربر ممکن است گهگاه کمی تأخیر حس کند اما در حدی نیست که خیلی اذیت شود. بهتر است برای ارتقاء تجربه، تلاش کنیم INP را به زیر ۲۰۰ms برسانیم.
  • INP ضعیف (قرمز): اگر INP صفحه بیش از ۵۰۰ میلی‌ثانیه باشد، ضعیف (Poor) تلقی می‌شود. یعنی حداقل یک تعامل کاربر در صفحه به‌شدت کند بوده است. چنین وضعیتی احتمالاً باعث ناراضی شدن کاربر و شاید ترک سایت می‌شود و باید فوراً بهینه‌سازی شود.

گوگل در گزارش Core Web Vitals خود، درصدی از بازدیدهای «خوب»، «متوسط» و «ضعیف» را نشان می‌دهد. برای اینکه یک صفحه “قبول” شود، حداقل ۷۵٪ بازدیدهایش باید INP خوب (سبز) داشته باشند. به بیان دیگر، p75 ≤ 200ms به عنوان شرط Pass شدن INP در نظر گرفته می‌شود. اگر INP صفحه شما در محدوده زرد یا قرمز است، یعنی برای درصد قابل توجهی از کاربران کند بوده و بهتر است به فکر بهبود آن باشید.

کدام تعاملات در INP حساب می‌شوند؟ (و کدام نمی‌شوند)

همه انواع تعاملات کاربر در محاسبه INP در نظر گرفته نمی‌شوند. تمرکز INP بر تعاملاتی است که معمولاً نیاز به پاسخ نرم‌افزاری دارند و تاخیرشان به تجربه کاربری لطمه می‌زند. بر اساس تعریف: INP فقط تعاملات زیر را رصد می‌کند:

  • کلیک با موس (Mouse click)
  • تاچ روی صفحه لمسی (Tap touch)
  • فشردن کلید کیبورد (چه فیزیکی چه کیبورد روی صفحه لمسی)

به عبارت دیگر هر تعاملی که منجر به رخدادهایی مثل mousedown/mouseup/click، یا لمس (pointerdown/pointerup) و یا رویدادهای کیبورد (keydown/keyup) شود، در INP لحاظ می‌شود. این‌ها تعاملاتی هستند که معمولاً یا توسط جاوااسکریپت کنترل می‌شوند یا حداقل باعث تغییراتی در صفحه می‌گردند که قابل مشاهده است.

چه تعاملاتی در محاسبه INP در نظر گرفته نمیشود :

اما کاربر به روش‌های دیگری هم با صفحه تعامل می‌کند که در INP حساب نمی‌شوند:

  • اسکرول کردن صفحه با موس یا لمس (Scroll)
  • بردن نشانگر روی عناصر (Hover)
  • بزرگ‌نمایی (Zoom) یا درگ کردن بدون کلیک
    این موارد در INP دیده نمی‌شوند. چرا؟ چون معمولاً اسکرول و هاور جزء تعاملات مداومی هستند که خودشان بازخورد آنی و جداگانه‌ای ندارند یا توسط مرورگر به صورت پیش‌فرض روان اجرا می‌شوند. البته، اگر حین اسکرول کردن کدی اجرا شود (مثلاً رویداد onscroll که محتوایی لود کند)، آن کد می‌تواند روی INP اثر داشته باشد که در ادامه می‌بینیم (هرچند خود عمل اسکرول به عنوان یک تعامل مستقل لحاظ نمی‌شود).

نکته دیگر در مورد Iframe ها:

وقتی کاربر داخل یک iframe کاری انجام می‌دهد—مثلاً روی ویدیویی که داخل iframe پخش می‌شود کلیک می‌کند—مرورگر این تعامل را برای صفحه اصلی (والد) حساب می‌کند، نه فقط iframe. چون از دید کاربر، کل صفحه یکی است و اصلاً متوجه نمی‌شود که آن ویدیو یا بخش، داخل یک iframe است.

به همین دلیل، تعاملات داخل iframe هم وارد محاسبه INP صفحه اصلی می‌شوند. این موضوع برای توسعه‌دهندگانی که از ابزارهای RUM (Real User Monitoring) استفاده می‌کنند خیلی مهم است. چون اسکریپت‌های این ابزارها معمولاً نمی‌توانند به محتوای داخل iframe دسترسی داشته باشند. بنابراین ممکن است داده‌هایی که RUM جمع‌آوری می‌کند، با داده‌هایی که گوگل در CrUX (Chrome User Experience Report) می‌بیند کمی تفاوت داشته باشد.

چطور INP صفحه‌مان را اندازه بگیریم و بررسی کنیم؟

حالا که تئوری قضیه را متوجه شدیم، سؤال مهم این است: چطور INP صفحه‌مان را اندازه بگیریم و بررسی کنیم؟ 😍 خوشبختانه ابزارهای مختلفی برای این کار وجود دارد. برخی ابزارها با شبیه‌سازی در محیط آزمایشگاهی (Lab) به ما اجازه می‌دهند INP را تست کنیم، و برخی با داده‌های واقعی کاربران (Field) وضعیت دنیای واقعی را به ما نشان می‌دهند. در ادامه مهم‌ترین ابزارهای هر دو دسته را معرفی می‌کنیم.

ابزارهای آزمایشگاهی (Lab) برای تست INP

این ابزارها در محیط توسعه یا تست به شما اجازه می‌دهند INP را شبیه‌سازی و اندازه‌گیری کنید. مزیت‌شان این است که می‌توانید قبل از انتشار تغییرات، عملکرد را بسنجید یا روی سیستم خودتان مشکلات را debug کنید. اما فراموش نکنید که داده Lab همیشه دقیقاً منعکس‌کننده واقعیت کاربران نیست (مثلاً نوع دستگاه یا سرعت اینترنت واقعی آن‌ها ممکن است متفاوت باشد).

1. Chrome DevTools (Lighthouse Timespan Mode):

ابزار توسعه‌دهندگان کروم قابلیت جدیدی برای تست INP اضافه کرده است. شما می‌توانید از تب Lighthouse در DevTools و انتخاب حالت Timespan استفاده کنید. سپس خودتان چند تعامل (مثل کلیک) روی صفحه انجام دهید و ضبط کنید. Lighthouse گزارشی شامل INP را تولید خواهد کرد

در این حالت، شما کنترل دارید که چه تعاملاتی را تست کنید. برای استفاده: DevTools را باز کنید (مثلاً F12)، به تب Lighthouse بروید، حالت را روی Timespan بگذارید، گزینه Performance را تیک بزنید و Start را بزنید. حالا در حالی که ضبط فعال است، با صفحه تعامل کنید (مثلاً دکمه‌هایی را کلیک کنید که می‌خواهید تست شوند). پس از Stop کردن، گزارشی می‌بینید که در آن INP محاسبه شده است. تصویر زیر بخش تنظیم Lighthouse را نشان می‌دهد:

inp-recording-in-dev-tools-step-by-step

(How to Measure Interaction to Next Paint (INP) – Onely)


تنظیم Lighthouse در DevTools برای تست INP: حالت Timespan را انتخاب کنید و Performance را تیک بزنید. سپس Start timespan را کلیک کرده و تعاملات دلخواه را انجام دهید.

2. افزونه Web Vitals برای کروم:

این یک افزونه رسمی گوگل است که با نصب آن روی Chrome، می‌توانید در هر صفحه‌ای Core Web Vitals (LCP, FID/INP, CLS و غیره) را مشاهده کنید.

روش کار:

افزونه را از Chrome Web Store نصب کنید. حالا هر صفحه‌ای را باز کنید و پس از انجام یک تعامل (مثل کلیک)، روی آیکن افزونه کلیک کنید تا مقادیر متریک‌ها را ببینید. برای INP، باید حتماً یک تعامل انجام دهید تا عدد آن ظاهر شود (چون بدون تعامل مقدار ندارد). مزیت این افزونه این است که خیلی سریع می‌توانید وضعیت را ببینید. ولی دقت کنید که فقط آخرین تعامل ثبت می‌شود – اگر بخواهید تعامل دیگری را بسنجید باید صفحه را رفرش کنید و دوباره تست کنید.

در تصویر زیر نمونه خروجی این افزونه را می‌بینید که INP را هم نمایش می‌دهد (در نسخه‌های جدید، به جای FID، متریک INP نشان داده می‌شود):

نمایش Core Web Vitals (از جمله INP) در افزونه Web Vitals کروم پس از یک تعامل. مقادیر نشان می‌دهند که INP این صفحه 8ms بوده که عالی (سبز) است. توجه: برای تست تعاملات مختلف باید صفحه را نوسازی (reload) کنید.

3. INP Debugger (ابزار DebugBear):

اگر دوست دارید ابزار خودکار تعاملی داشته باشید، وب‌سایت DebugBear یک ابزار رایگان به نام INP Debugger ارائه داده است. این ابزار صفحه‌ی شما را لود می‌کند، به طور خودکار روی المان‌های قابل کلیک شما کلیک می‌کند و تأخیر INP را برای هرکدام گزارش می‌کند. در واقع یک ربات است که سایت را شبیه‌سازی می‌کند تا ببیند کدام دکمه یا لینک تعامل کندی دارد.

مثلاً اگر دکمه “ثبت سفارش” شما کند واکنش نشان دهد، این ابزار نشان می‌دهد. برای استفاده می‌توانید به سایت DebugBear مراجعه کنید و URL صفحه را وارد کنید. ترکیب این روش با داده‌های میدانی مفید است چون به شما می‌گوید کدام عنصر باعث INP بالا شده است (چیزی که ابزارهای صرفاً میدانی مثل PSI مستقیم نشان نمی‌دهند). البته فراموش نکنیم که Lab نمی‌تواند تمام پیچیدگی‌های دنیای واقعی (مانند تنوع دستگاه‌ها و سرعت‌ها) را پوشش دهد، اما برای شروع عیب‌یابی عالیست.

ابزارهای میدانی (Field) برای مشاهده INP در دنیای واقعی

داده‌های میدانی بسیار مهم‌اند، چون واقعاً تجربه کاربران واقعی را نشان می‌دهند. ممکن است سایتی روی سیستم شما سریع باشد ولی برای کاربران کشورهای دیگر یا دستگاه‌های ضعیف کند عمل کند. ابزارهای زیر با استفاده از داده‌های واقعی (معمولاً از گزارش کرومUX یا RUM) به شما تصویر دقیقی از INP می‌دهند:

1. PageSpeed Insights (گزارش تجربه کاربر کروم):

PageSpeed Insights یا به اختصار PSI یک ابزار آنلاین گوگل است که هم داده Lab و هم داده Field را نشان می‌دهد. قسمت بالای گزارش PSI اگر داده‌ای از CrUX (گزارش تجربه کاربر کروم) برای سایت شما موجود باشد، Core Web Vitals واقعی ۲۸ روز اخیر را نمایش می‌دهد.

در نسخه‌های جدید PSI، به جای FID اکنون INP گزارش می‌شود. شما می‌توانید برای سایت خود (یا هر URL مشخص) در PSI ببینید چه درصدی از بازدیدها INP خوب/متوسط/ضعیف داشته‌اند و مقدار صدک ۷۵ (p75) INP چند میلی‌ثانیه بوده است.

این نکته را توجه داشته باشید که اگر سایت شما جدید باشد یا به اندازه ترافیک نداشته باشد در این قسمت این سایت به شما) اطلاعاتی مبنی بر INP سایت را نشان نمیدهد من اینجا عکس گزارش سایت دیجیکالا را برای شما گذاشتم تا ببینید این گزارش به چه شکلی خواهد بود 👇👇👇😊 .)

اگر INP شما “نیاز به بهبود” یا “ضعیف” باشد، در PSI با رنگ زرد یا قرمز مشخص می‌شود. PSI ابزار سریعی برای یک نگاه اجمالی است. کافیست به آدرس pagespeed.web.dev بروید، URL را وارد کنید و صبر کنید تا تحلیل انجام شود. بخش Field آن به شما می‌گوید “آیا من مشکل INP دارم؟” اما مشخص نمی‌کند مشکل دقیقاً کجاست.

2. کنسول جستجوی گوگل (Google Search Console – گزارش Core Web Vitals):

اگر سایت خود را در GSC ثبت کرده باشید، در بخش Page Experience > Core Web Vitals می‌توانید گزارش کاملی از وضعیت INP (و بقیه شاخص‌ها) برای صفحات‌تان ببینید. این گزارش بر اساس داده‌های واقعی کاربران کروم است و URLهای شما را به سه گروه خوب، متوسط، ضعیف دسته‌بندی می‌کند. مثلاً ممکن است ببینید «۱۰۰ صفحه شما INP خوب دارند، ۳۰ صفحه نیاز به بهبود دارند، ۵ صفحه ضعیف‌اند». اگر روی هر دسته کلیک کنید، جزئیات بیشتری نمایش می‌دهد. تصویر زیر نمونه‌ای از این گزارش را نشان می‌دهد:

گزارش Core Web Vitals در کنسول گوگل برای نسخه موبایل: نشان می‌دهد ۱۹۴ آدرس URL دارای مشکل INP بوده‌اند (در دسته Needs Improvement). با کلیک روی این ردیف، می‌توان جزئیات گروه صفحات و مقادیر INP را دید.

در GSC می‌توانید بر اساس موبایل یا دسکتاپ تفکیک را ببینید و حتی گروه‌های URL (مثلاً صفحات مشابه) که INP بد دارند را پیدا کنید. محدودیت GSC این است که نام المانی که مشکل دارد را مشخص نمی‌کند و فقط URLها را گروه‌بندی می‌کند. اما برای این که بفهمیم آیا اصولاً INP مشکلی دارد و کجاها، نقطه شروع خوبی است. از همین‌جا ممکن است تصمیم بگیرید صفحه X را که INP بدی دارد در ابزارهای Lab مثل DevTools عیب‌یابی کنید.

3. ساخت داشبورد Core Web Vitals با استفاده از CrUX

گوگل از مرورگر کروم اطلاعاتی درباره تجربه واقعی کاربران جمع‌آوری می‌کند (درصورتی‌که کاربران رضایت داده باشند). این اطلاعات در پایگاه داده‌ای به نام Chrome UX Report (یا CrUX) ذخیره می‌شود. شما می‌توانید به این اطلاعات از طریق Looker Studio (قبلاً Google Data Studio) دسترسی پیدا کنید و برای دامنه خود، یک داشبورد اختصاصی Core Web Vitals بسازید.

✅ مرحله 1: ورود به ابزار CrUX Dashboard از طریق لینک داده شده.

✅ مرحله 2: وارد کردن دامنه سایت

در فیلدی که ظاهر می‌شود: آدرس سایت خود را بدون مسیر اضافی وارد کنید. فقط دامنه اصلی.

✅ مرحله 3: اتصال به Looker Studio

پس از وارد کردن دامنه: نیازی به تغییر تنظیمات نیست؛ فقط روی دکمه “Create Report” یا “ایجاد گزارش” کلیک کنید. روی دکمه “Connect” کلیک کنید. در صفحه‌ی جدیدی که باز می‌شود، اطلاعات اولیه CrUX سایت شما نشان داده می‌شود.

✅ مرحله 4: مشاهده و تحلیل داشبورد

اگر همه چیز درست انجام شده باشد، یک داشبورد کامل برای سایت شما ساخته می‌شود که شامل اطلاعات زیر است: نمودار درصد بازدیدهای با تجربه خوب (Good) برای هر شاخص – شاخص‌های Core Web Vitals مانند INP، LCP، CLS داده‌ها به‌صورت تفکیک‌شده برای موبایل و دسکتاپ روند تاریخی (۶ تا ۱۲ ماه گذشته) برای هر معیار

🧠 نکات تکمیلی

این اطلاعات از کاربران واقعی جمع‌آوری شده‌اند و نمایانگر تجربه واقعی بازدیدکنندگان شما هستند. اگر سایت شما در CrUX وجود نداشته باشد (به دلیل کم بودن ترافیک)، ممکن است داشبورد ساخته نشود یا داده‌ای نمایش داده نشود.

4. داده‌های میدانی سفارشی (RUM) با کتابخانه web-vitals:

در نهایت، اگر می‌خواهید دقیقاً خودتان داده‌های INP را جمع‌آوری کنید (مثلاً برای هر کاربر که به سایت می‌آید)، می‌توانید از کتابخانه جاوااسکریپتی web-vitals استفاده کنید. این کتابخانه رسمی گوگل به شما اجازه می‌دهد در کد سایتتان، متریک‌های وب ویتال (شامل INP) را برای هر کاربر جمع‌آوری کنید و به سرور یا آنالیتیکس خود بفرستید.

این روش پیشرفته‌تر است و نیاز به کدنویسی دارد (در بخش بعد یک نمونه کد برای INP خواهیم دید). مزیت این روش این است که شما می‌توانید دقیقاً بفهمید کدام عنصر با چه تعاملی و در چه حالتی باعث INP بد شده است. حتی نسخه Attribution این کتابخانه جزئیات بیشتری مثل inputDelay، processingDuration و presentationDelay را برای هر تعامل می‌دهد. بسیاری از شرکت‌ها داده‌های RUM را با این روش یا سرویس‌های آماده (مانند Elastic RUM, SpeedCurve, DebugBear و …) جمع می‌کنند تا دائماً عملکرد واقعی را زیر نظر داشته باشند.

در کل، پیشنهاد می‌کنم ابتدا با ابزارهای میدانی مثل PSI/GSC ببینید آیا مشکلی هست و کجا هست، سپس با ابزارهای آزمایشگاهی مانند DevTools و INP Debugger دقیق‌تر بررسی کنید مشکل از چیست. ترکیب این دو رویکرد بهترین نتیجه را می‌دهد.

نمونه کد: محاسبه INP با web-vitals و ارسال به Google Analytics

حالا بیایید یک مثال عملی ببینیم تا درک بهتری پیدا کنیم که چطور می‌شود INP را در کد واقعی اندازه گرفت. فرض کنیم می‌خواهیم با کمک کتابخانه web-vitals مقدار INP کاربران را جمع‌آوری کنیم و به Google Analytics 4 ارسال کنیم تا آنجا تحلیل کنیم. کد زیر (برگرفته از مستندات رسمی گوگل) این کار را انجام می‌دهد:

import { onINP } from 'web-vitals/attribution';

function sendToGoogleAnalytics({ name, value, id, attribution }) {
  const { eventEntry, eventTarget, eventType, loadState } = attribution;
  const { startTime, processingStart, processingEnd, duration, interactionId } = eventEntry;

  const eventParams = {
    metric_inp_value: value,
    metric_id: id,
    metric_inp_event_target: eventTarget,
    metric_inp_event_type: eventType,
    metric_inp_load_state: loadState,
    metric_inp_start_time: startTime,
    metric_inp_processing_start: processingStart,
    metric_inp_processing_end: processingEnd,
    metric_inp_duration: duration,
    metric_inp_interaction_id: interactionId
  };

  if (typeof gtag === 'function') {
    gtag('event', name, eventParams);
  }
}

if (document.readyState === 'complete' || document.readyState === 'interactive') {
  onINP(sendToGoogleAnalytics);
} else {
  window.addEventListener('DOMContentLoaded', () => {
    onINP(sendToGoogleAnalytics);
  });
}

توضیح کد به زبان ساده: ابتدا از نسخه attribution کتابخانه web-vitals، تابع onINP را وارد می‌کنیم. این تابع به ما اجازه می‌دهد هنگام محاسبه شدن INP (مثلاً وقتی کاربر صفحه را ترک می‌کند یا بعد از تعامل)، کدی اجرا کنیم. ما یک تابع sendToGoogleAnalytics نوشتیم که اطلاعات INP را گرفته و یک رویداد به GA ارسال می‌کند.

در این تابع داریم جزئیاتی مثل مقدار INP، نوع رویداد (کلیک یا کیبورد)، هدف رویداد (CSS selector عنصر)، وضعیت لود صفحه (آیا در حال بارگیری بود یا کامل لود شده بود) و زمان‌های شروع/پایان پردازش و غیره را جمع‌آوری می‌کنیم. سپس با فراخوانی gtag('event', ...) یک event سفارشی به GA4 می‌فرستیم. در پایان، onINP(sendToGoogleAnalytics) را صدا می‌زنیم تا هر زمان مرورگر مقدار INP را محاسبه کرد، داده‌ها را از طریق تابع ما گزارش کند.

با این روش، در پنل GA4 می‌توانید این رویدادها را دریافت و روی آن‌ها آنالیز کنید (البته باید در GA4 یک سری شاخص‌های سفارشی (Custom Dimensions/Metrics) برای این پارامترها تعریف کنید تا گزارش‌پذیر شوند). سپس قادر خواهید بود مثلاً میانگین INP را بر اساس نوع دستگاه یا نوع صفحه در آنالیتیکس مشاهده کنید یا حتی ببینید بیشترین INP مربوط به کدام المان‌ها بوده است (چون metric_inp_event_target را فرستادیم).

این نمونه کد نشان می‌دهد چطور می‌توانید داده‌های دقیق میدانی در مورد INP جمع کنید. البته پیاده‌سازی عملی ممکن است پیچیدگی‌های بیشتری داشته باشد (مثلاً محدود کردن ارسال‌ها با navigator.sendBeacon به جای gtag برای عدم بلاک شدن، یا ارسال به سرور خودتان). اما هدف این بود که ببینیم اصولاً INP چگونه در کد قابل اندازه‌گیری است. اگر به این مبحث علاقه دارید، منابع بیشتری در این زمینه موجود است (از جمله راه‌اندازی از طریق Google Tag Manager با template آماده توسط Simo Ahava).

راهکارهای بهبود INP (تجربه بهتر کاربر)

خب، فرض کنیم INP سایت ما خوب نیست و تصمیم داریم آن را بهتر کنیم. چه کارهایی می‌توانیم انجام دهیم؟ 😊 از آن‌جایی که INP سه بخش Input Delay، Processing و Presentation را شامل می‌شود، راهکارهای بهبود هم در سه حوزه هستند: کاهش تأخیر ورودی، بهینه‌سازی پردازش رویدادها و تسریع نمایش فریم بعدی. در ادامه هر کدام را با بیان ساده و مثال توضیح می‌دهیم:

کاهش Input Delay (کوتاه کردن تأخیر شروع واکنش)

تاخیر ورودی زمانی رخ می‌دهد که کاربر کلیک کرده ولی مرورگر هنوز واکنشی نشان نداده (هنوز event handler شروع نشده). دلیل اصلی این اتفاق مشغول بودن ترد اصلی مرورگر است. پس راه‌حل عمومی این است که کاری کنیم ترد اصلی (main thread) آماده و خالی باشد تا به محض ورودی کاربر، بتواند آن را پردازش کند.

چند راهکار عملی:

  • جلوگیری از بلاک شدن ترد اصلی حین لود: موقع بارگذاری صفحه، اگر اسکریپت‌های حجیم اجرا شوند ممکن است مدت زیادی CPU را اشغال کنند و کاربر اگر در همان حین تعامل کند، ورودی او در صف می‌ماند. با تقسیم‌بندی کد (Code-splitting) و استفاده از صفت‌های defer و async در تگ اسکریپت، می‌توانید کاری کنید اسکریپت‌ها تا حد ممکن بار صفحه را متوقف نکنند. همچنین ارزیابی تنبل بعضی اسکریپت‌ها – یعنی اجرا کردنشان زمانی که واقعاً لازم‌اند نه هنگام لود – کمک می‌کند. هدف این است که بلافاصله بعد از render اولیه صفحه، ترد اصلی سبک باشد.
  • حذف یا به تعویق انداختن کارهای غیر ضروری: مثلا اگر در onLoad کارهایی مانند پردازش داده یا فراخوانی‌هایی انجام می‌دهید، ببینید می‌شود آن‌ها را عقب‌تر انداخت (مثلاً با setTimeout چند ثانیه بعد انجام شوند) یا در Web Worker‌ها انجام شوند تا main thread را اشغال نکنند.
  • رسیدگی به صف تعاملات سریع: اگر کاربران ممکن است چند تعامل پشت سر هم بزنند (مثلاً دوبار کلیک کنند)، مطمئن شوید که تعاملات قبلی سریع هندل می‌شوند و صف طولانی تشکیل نمی‌دهند. در غیر این صورت input delay تعاملات بعدی افزایش می‌یابد.

بطور خلاصه، برای کاهش Input Delay باید هر چیزی که ممکن است همزمان با ورودی کاربر روی thread اصلی در حال اجرا باشد را کم کنید یا خرد کنید. تا جایی که می‌توانید طولانی‌ترین taskها را حذف یا کوتاه کنید (Long Taskها قاتل Input Delay هستند).

کاهش زمان پردازش رویداد (بهینه‌سازی Event Handlerها)

بخش دوم INP مربوط به اجرای کدهای شما در واکنش به تعامل است. مثلا وقتی کاربر روی دکمه کلیک می‌کند، ممکن است یک فانکشن اجرا شود که چندین کار انجام می‌دهد: تغییر متن دکمه، ارسال درخواست AJAX، به‌روز کردن چند بخش دیگر صفحه و … . هرچه این پردازش بیشتر طول بکشد، مدت زمان Processing بیشتر می‌شود. پس باید پردازش هر تعامل را تا حد امکان سریع و سبک نگه داریم.

راهکارهای مهم:

  • تا می‌توانید کار کمتری در event handler انجام دهید: اصل کلی این است که فقط کاری که ضروری است در لحظه انجام شود را همان موقع انجام دهید؛ بقیه کارها را عقب بیندازید. به عنوان مثال، فرض کنید کاربر متنی را تایپ می‌کند و ما همزمان باید چند چیز را به‌روز کنیم: نشان دادن متن تایپ‌شده، به‌روز کردن شمارش کلمات، بررسی املای کلمات، ذخیره متن در سرور. از این موارد، فقط نمایش فوری متن برای کاربر حیاتی است. می‌توانیم بروزرسانی شمارش کلمات، بررسی املاء و ذخیره‌سازی را همگی با کمی تأخیر انجام دهیم. این کار را می‌توان با ترکیب requestAnimationFrame و setTimeout انجام داد تا مطمئن شویم ابتدا یک فریم جدید با متن جدید نمایش داده می‌شود و سپس سایر پردازش‌ها در پس‌زمینه انجام شوند. (در کد نمونه‌ای که بالاتر دیدیم، از همین ترفند استفاده شده بود). با این روش duration تعامل کاهش می‌یابد بدون اینکه عملکرد نهایی از بین برود – فقط کارهای غیرضروری را کمی عقب می‌اندازیم.
  • تکه‌تکه کردن کارهای سنگین: اگر ناچارید در واکنش به یک تعامل کار محاسباتی سنگینی انجام دهید، آن را به چند بخش کوچک بشکنید. مثلاً به جای یک loop خیلی بزرگ که 200ms طول می‌کشد، می‌شود با setTimeout آن را در چند قسمت انجام داد تا بینشان فرصت رندر باشد. حتی می‌توانید از requestIdleCallback استفاده کنید تا مرورگر هر وقت بیکار بود قسمت بعدی کار را انجام دهد. اینطوری Main Thread قفل نمی‌شود و اگر کاربر تعامل دیگری انجام دهد، مرورگر می‌تواند بین این قطعات، ورودی جدید را هم رسیدگی کند.
  • Debounce یا Throttle کردن رویدادهای مکرر: برخی رویدادها مثل scroll یا mousemove ده‌ها بار در ثانیه فایر می‌شوند. اگر هر بار کد سنگینی اجرا کنید، ترد اشغال می‌شود. با تکنیک Debouncing می‌توانید کاری کنید که مثلا تا کاربر اسکرول را تمام نکرده، کد شما اجرا نشود یا فقط هر ۱۰۰ms یکبار اجرا شود. این کار در مورد سایت redBus بسیار مفید بود؛ آن‌ها event مربوط به اسکرول را Debounce کردند تا به جای صدها بار، فقط چند بار اجرا شود و ترد اصلی فرصت نفس کشیدن داشته باشد (How redBus improved their website’s Interaction to Next Paint (INP) and increased sales by 7%  |  web.dev).
  • عدم انجام کارهای خطرناک در حین رویداد: منظور از خطرناک، کارهایی است که ممکن است باعث Reflow/Relayout همزمان شوند. مثلا دستکاری مستقیم CSSهایی که Layout را تغییر می‌دهند و بلافاصله بعدش پرسیدن offsetHeight از همان عنصر، مرورگر را مجبور می‌کند همان لحظه Layout را بازمحاسبه کند (پدیده‌ای به نام Layout Thrashing). این اتفاق می‌تواند پردازش را طولانی و غیرضروری کند. سعی کنید اینگونه کدها را حذف یا اصلاح کنید که یا Layout آخر کار انجام شود یا از CSS‌های مدرن استفاده کنید که هزینه کمتری دارند.

در کل هدف این بخش: کدهای event handler خود را مثل طلا ارزشمند بدانید! 😄 هر خط غیرضروری را حذف کنید، کارها را موازی یا تأخیری کنید و نگذارید یک تعامل تبدیل به یک Long Task بزرگ شود. با این کار نه تنها INP بهبود می‌یابد بلکه سایت شما در کل احساس خیلی چابک‌تری خواهد داشت.

کاهش Presentation Delay (سرعت رساندن تغییرات به صفحه)

آخرین بخش، زمان بعد از پایان کدهای شما تا نمایش نتیجه به کاربر است. این بیشتر به عملکرد مرورگر در رندر کردن تغییرات مربوط می‌شود. اگر تغییرات DOM سنگین باشند یا مرورگر مجبور شود حجم زیادی از عناصر را دوباره بکشد، این زمان افزایش می‌یابد. چند راه برای بهبود:

  • کاهش حجم DOM و تغییرات: هرچه تعداد المان‌های صفحه بیشتر باشد، رندر آن زمان بیشتری می‌گیرد. سعی کنید DOM را سبک نگه دارید؛ المان‌های غیرضروری را حذف کنید. برای مثال اگر لیستی از ۱۰۰۰ آیتم دارید که فقط ۲۰ تای اول نمایش داده می‌شوند، بارگذاری بقیه در DOM از ابتدا غیرضروری است. می‌توانید از تکنیک virtualization یا paginate کردن استفاده کنید تا همیشه فقط بخش در حال نمایش در DOM باشد.
  • استفاده از CSS هوشمند (مانند content-visibility): ویژگی CSS به نام content-visibility: auto می‌تواند المان‌های خارج از صفحه (Off-screen) را از محاسبات رندر خارج کند تا زمانی که نزدیک نمایش شدن در صفحه باشند. این یعنی مرورگر آن بخش‌ها را رندر نمی‌کند تا وقتی کاربر اسکرول کند و به آنجا برسد. استفاده درست از این ویژگی می‌تواند حجم کاری که مرورگر برای رندر هر فریم باید انجام دهد را کاهش دهد و در نتیجه Presentation Delay کمتر شود.
  • به‌روزرسانی‌های هوشمند DOM: مراقب باشید که در واکنش به رویداد، چه چیزهایی از صفحه را تغییر می‌دهید. اگر بتوانید فقط بخشی از صفحه را که لازم است تغییر دهید و نه همه را، رندر سریع‌تر انجام می‌شود. مثلاً اگر با آمدن داده جدید لازم نیست کل جدول ری‌رندر شود و فقط همان یک ردیف اضافه می‌شود، اینطور پیاده کنید. فریم‌ورک‌های UI مدرن (React/Vue و …) معمولاً در این زمینه خوب عمل می‌کنند و فقط diff را اعمال می‌کنند.
  • سبک کردن استایل‌ها و انیمیشن‌ها: انیمیشن‌های CSS ترجیحاً با transform/opacity انجام شوند که به layout جدید نیاز ندارند. هر چیزی که باعث layout یا paint سنگین در DevTools نشان داده می‌شود را بهبود دهید (مثلاً shadow بزرگ روی صدها المان ممکن است کند باشد). برای کاهش Presentation Delay، می‌توانید از ابزار Performance در DevTools استفاده کنید و ببینید آیا بخش‌هایی از Timeline با رنگ بنفش (Layout) یا سبز (Paint) طولانی شده‌اند. آنجاست که باید بهینه‌سازی کنید.

بطور خلاصه: رندر را آسان‌تر کنید. هر چه مرورگر زودتر بتواند frame جدید را نقاشی کند، INP کمتر می‌شود. این یعنی DOM کوچکتر، تغییرات کمتر و استفاده از تکنیک‌های بهینه رندر.

جمع‌بندی و نکات پایانی

در این مقاله سعی کردیم به زبان ساده اما جامع، مفهوم Interaction to Next Paint (INP) را بررسی کنیم. دیدیم که INP چرا معرفی شد و چطور نسبت به FID پیشرفت کرده است. یاد گرفتیم INP عملاً بدترین تأخیر تعاملی است که کاربر در یک صفحه تجربه می‌کند و آستانه‌های گوگل برای خوب یا بد دانستن آن چیست. همچنین باهم مرور کردیم که چه تعاملاتی در این سنجش حساب می‌شوند (کلیک‌ها و تاچ‌ها و کلیدها) و کدام‌ها نه.

بعد از آن، ابزارهای گوناگون برای اندازه‌گیری INP را دیدیم – از ابزارهای آزمایشگاهی مثل DevTools و Web Vitals extension گرفته تا گزارش‌های میدانی مثل PageSpeed Insights و کنسول گوگل. حتی یک نمونه کد عملی نوشتیم تا ببینیم چطور می‌توان INP را خودمان مانیتور کنیم.

سپس به بحث مهم راهکارهای بهبود INP پرداختیم: اینکه چگونه با کاهش تأخیر ورودی (از طریق آزاد نگه داشتن Thread)، با تقسیم‌بندی و بهینه‌سازی کدهای پردازشی، و با سبک کردن بار رندر می‌توانیم تجربه‌ای سریع‌تر و روان‌تر برای کاربر ایجاد کنیم. در خلال این بخش، مثال‌های واقعی و تکنیک‌های مفیدی مثل Debouncing اسکرول، استفاده از requestAnimationFrame، اجتناب از layout thrashing و استفاده از CSS جدید مثل content-visibility را ذکر کردیم.

امیدوارم این مطلب برایتان مفید بوده باشد. با به‌کارگیری این نکات می‌توانید وب‌سایت‌های سریع‌تر و واکنش‌گراتری بسازید که هم کاربران و هم گوگل عاشق‌شان باشند! به یاد داشته باشید، تجربه کاربر حرف اول را می‌زند و سرعت واکنش یکی از ارکان اصلی این تجربه است. پس از همین امروز به فکر بهبود INP سایت‌تان باشید. موفق باشید! 🚀