شناسایی دلایل INP ضعیف

پاسخگویی ضعیف به تعامل‌ها باعث می‌شود این تصور ایجاد شود که صفحه کند است یا حتی کاملاً خراب است. «تعامل با نقاشی بعدی» (INP) سنجه‌ای براساس Event Timing API است. این سنجه بدترین تعامل (منهای برخی داده‌های پرت) را به‌عنوان معیاری برای پاسخگویی صفحه اندازه‌گیری می‌کند.

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

‫Event Timing API امکان تقسیم مدت INP به سه بخش فرعی را فراهم می‌کند: تأخیر ورودی (پردازشی که درحال‌حاضر هنگام وقوع تعامل درحال انجام است)، مدت پردازش (تأخیرهای ناشی از نتیجه مستقیم تعامل)، و تأخیر ارائه (تأخیرهای ناشی از رندر کردن فریم بعدی پس‌از تعامل). این کار کمک می‌کند تا به‌جای رفتن مستقیم به کد تعامل، مشخص شود که آیا مشکل در کد دیگری است، کد جاوا اسکریپت تعامل، یا پردازش مرورگر که به‌روزرسانی‌های رندر را انجام می‌دهد.

می‌توان اطلاعات آماری بیشتری درباره جاوا اسکریپت، محاسبه مجدد سبک، و کار چیدمان که تعامل را به‌تأخیر می‌اندازد جمع‌آوری کرد. ردیابی کامل عملکرد بااستفاده از JS Self-Profiling API راه‌حلی سنگین است که احتمالاً باعث مشکلات عملکردی می‌شود. Long Animation Frames API یک میانای برنامه‌سازی کاربردی سبک است که می‌تواند در این زمینه برای شناسایی جاوا اسکریپت با اجرای کند و تشخیص بین محاسبه مجدد سبک و هزینه‌های چیدمان درطول تعاملات INP استفاده شود:

  • سبک و چیدمان اجباری در سطح اسکریپت (forcedStyleDuration و forcedLayoutDuration): بازمحاسبه‌های سبک همگام (مانند فراخوانی getComputedStyle() پس‌از جهش‌های DOM) و چیدمان‌ها/بازجریان‌های اجباری (مانند خواندن getBoundingClientRect() یا offsetWidth پس‌از جهش‌ها) را در اسکریپت درحال اجرا درطول تأخیر ورودی یا مدت پردازش گزارش می‌کند.
  • سبک و چیدمان پرداز سطح فریم (styleDuration و layoutDuration): زمان صرف‌شده برای محاسبه مجدد سبک‌ها درمقابل به‌روزرسانی چیدمان درطول به‌روزرسانی پرداز فریم را گزارش می‌کند، که به توضیح تأخیر ارائه بالا کمک می‌کند.

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

نحوه پیاده‌سازی

محاسبه INP از Event Timing API خام پیچیده است و چندین تفاوت ظریف دارد. توصیه می‌شود برای جمع‌آوری این داده‌ها از ابزار یا کتابخانه RUM استفاده کنید.

‫web-vitals یک کتابخانه متن‌باز از Google است که «سنجه‌های حیاتی وب» ازجمله INP را محاسبه می‌کند و همچنین شامل زیربخش‌ها و داده‌های فریم پویانمایی طولانی برای تعامل INP است.

دریافت ارجاع برای تعامل‌های INP بااستفاده از کتابخانه web-vitals

کتابخانه 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 استفاده کنید تا مشخص شود که آیا تأخیر به‌دلیل اجرای جاوا اسکریپت (تأخیر ورودی)، جاوا اسکریپت گرداننده‌های رویداد برای تعامل (مدت پردازش)، یا رندر کردن بعدی (تأخیر ارائه) است.
  • باید تلاش کنید بزرگ‌ترین جاوا اسکریپت مسدودکننده را به‌عنوان جزئیات بیشتر، به‌ویژه برای تأخیر ورودی و مدت پردازش، شناسایی کنید.
  • باید هنگام تشخیص مدت‌زمان پردازش بالا یا تأخیر ارائه، بین محاسبه مجدد سبک (styleDuration، forcedStyleDuration) و چیدمان (layoutDuration، forcedLayoutDuration) تمایز قائل شوید: زمان‌های سبک بالا نشان‌دهنده گزینشگرهای CSS پرهزینه یا باطل‌سازی‌های گسترده است، درحالی‌که زمان‌های چیدمان بالا نشان‌دهنده گلوگاه‌های هندسه DOM یا کوبش چیدمان همگام است.
  • توصیه می‌شود برای ارائه این جزئیات بیشتر، Long Animation Frames API را بر جایگزین‌هایی مانند JS Self-Profiling API که سربار زمان اجرای بالاتری دارد ترجیح دهید.
  • اگر راهکار RUM دیگری وجود ندارد، حتماً از کتابخانه web-vitals استفاده کنید. این ابزار می‌تواند تعامل INP را شناسایی کند و شامل اطلاعاتی درباره زیربخش‌ها و اسکریپت‌هایی است که درطول تعامل اجرا شده‌اند (بااستفاده از Long Animation Frames API).
  • باید اطلاعات لازم را به‌جای اینکه فقط به‌صورت محلی ثبت کنید، به سرویس تجزیه‌وتحلیل ارسال کنید.

پشتیبانی مرورگر و راهبردهای جایگزین

Event Timing API در اکثر مرورگرهای مدرن دردسترس است و برای محاسبه INP و زیربخش‌های INP ضروری است. برای مرورگرهایی که از این میانای برنامه‌سازی کاربردی پشتیبانی نمی‌کنند، INP قابل‌اندازه‌گیری نیست.

Long Animation Frames API جزئیات اختیاری و تکمیلی ارائه می‌دهد. می‌توان آن را بدون بازگشت به‌طور ایمن استفاده کرد. در بیشتر موارد، فرصت‌های عملکردی که شناسایی می‌کند برای مرورگرهای دیگر نیز اعمال خواهد شد.

اگر هدف «خط پایه» شما از 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 محاسبه کنید) تا سبک و چیدمان را باهم ترکیب کنید.