اندازه‌گیری کردن تعامل تا ترسیم بعدی (INP)

۱. مقدمه

این یک codelab تعاملی برای یادگیری نحوه اندازه‌گیری تعامل تا ترسیم بعدی (INP) بااستفاده از کتابخانه web-vitals است.

پیش‌نیازها

آنچه خواهید آموخت

  • نحوه افزودن کتابخانه web-vitals به صفحه و استفاده از داده‌های ارجاع آن.
  • از داده‌های اسنادی برای تشخیص اینکه کجا و چگونه بهبود «تأخیر در تعامل‌ها» را شروع کنید استفاده کنید.

آنچه نیاز خواهید داشت

  • رایانه‌ای با قابلیت شبیه‌سازی کد از GitHub و اجرای فرمان‌های npm.
  • ویرایشگر نوشتار.
  • نسخه‌ای جدید از Chrome برای کار کردن همه اندازه‌گیری‌های تعامل.

۲. تمام کردن راه‌اندازی

دریافت و اجرای کد

کد در مخزن 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/ مراجعه کنید.

امتحان کردن صفحه

این codelab از Gastropodicon (سایت مرجع محبوب آناتومی حلزون) برای کاوش مشکلات احتمالی INP استفاده می‌کند.

نماگرفتی از صفحه نسخه نمایشی Gastropodicon

برای اینکه متوجه شوید کدام تعامل‌ها کند هستند، با صفحه تعامل داشته باشید.

۳. آشنایی با Chrome DevTools

DevTools را از منو ابزارهای بیشتر > ابزارهای توسعه‌دهندگان، با کلیک راست روی صفحه و انتخاب بازرسی، یا با استفاده از میان‌بر صفحه‌کلید باز کنید.

در این کدآزمایی، از هر دو پانل عملکرد و کنسول استفاده خواهیم کرد. هرزمان بخواهید می‌توانید در زبانه‌های بالای «ابزارهای توسعه‌دهندگان» بین این موارد جابه‌جا شوید.

  • مشکلات INP اغلب در دستگاه‌های همراه رخ می‌دهد، بنابراین به شبیه‌سازی نمایشگر تلفن همراه بروید.
  • اگر در رایانه رومیزی یا رایانه کیفی آزمایش می‌کنید، عملکرد احتمالاً به‌طور قابل‌توجهی بهتر از دستگاه همراه واقعی خواهد بود. برای داشتن نگاهی واقع‌بینانه‌تر به عملکرد، روی چرخ‌دنده در بالا سمت چپ پانل عملکرد کلیک کنید، سپس کندی ۴ برابری CPU را انتخاب کنید.

نماگرفتی از پانل «عملکرد» DevTools در کنار برنامه، با انتخاب کند کردن واحد پردازش مرکزی ۴ برابر

۴. درحال نصب web-vitals

‫web-vitals کتابخانه جاوا اسکریپتی برای اندازه‌گیری سنجه‌های «حیاتی وب» است که کاربران شما تجربه می‌کنند. می‌توانید از کتابخانه برای ضبط این مقادیر استفاده کنید و سپس آن‌ها را به یک نقطه پایانی تجزیه‌وتحلیل برای تجزیه‌وتحلیل بعدی ارسال کنید، برای اهداف ما که تشخیص زمان و مکان تعاملات کند است.

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

این codelab از npm نصب می‌کند و مستقیماً نوشتار را بار می‌کند تا از پرداختن به فرایند ساخت خاصی اجتناب شود.

دو نسخه از web-vitals وجود دارد که می‌توانید استفاده کنید:

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

برای اندازه‌گیری INP در این codelab، ساختار اسنادی را می‌خواهیم.

با اجرای npm install -D web-vitals، web-vitals را به devDependencies پروژه اضافه کنید

‫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 را گزارش نمی‌کند. این رفتار برای ارسال پیام برای مواردی مانند تجزیه‌وتحلیل ایده‌آل است، اما برای اشکال‌زدایی تعاملی کمتر ایده‌آل است.

‫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 که باموفقیت در آن چاپ شده است

۵. ارجاع شامل چه مواردی است؟

بیایید با اولین تعاملی که اکثر کاربران با صفحه خواهند داشت شروع کنیم، یعنی چارگوش موافقت با کوکی.

بسیاری از صفحه‌ها اسکریپت‌هایی دارند که وقتی کاربر کوکی‌ها را می‌پذیرد باید به‌صورت هم‌زمان کوکی‌ها را راه‌اندازی کنند و باعث می‌شوند کلیک به تعاملی کند تبدیل شود. اینجا همین اتفاق می‌افتد.

برای پذیرفتن کوکی‌های (نسخه نمایشی)، روی بله کلیک کنید و اکنون به داده‌های INP که در کنسول DevTools ثبت شده است نگاهی بیندازید.

شیء داده INP در کنسول DevTools ثبت شد

این اطلاعات سطح بالا در هر دو ساختار استاندارد و اسنادی «وب‌سایت‌های حیاتی» دردسترس است:

{
  name: 'INP',
  value: 344,
  rating: 'needs-improvement',
  entries: [...],
  id: 'v4-1715732159298-8028729544485',
  navigationType: 'reload',
  attribution: {...},
}

مدت زمان از کلیک کاربر تا پرداز زدن بعدی ۳۴۴ میلی‌ثانیه بود—«تعامل با نقاشی بعدی» «نیازمند بهبود». آرایه 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: زمان بین زمانی که کاربر تعامل را شروع کرده است (برای مثال، روی موشواره کلیک کرده است) و زمانی که شنونده رویداد برای آن تعامل شروع به اجرا کرده است. در این حالت، حتی با وجود محدودسازی CPU، تأخیر ورودی فقط حدود ۲۷ میلی‌ثانیه بود.
  • ‫processingDuration: مدت زمانی که طول می‌کشد شنوندگان رویداد تا تکمیل اجرا شوند. اغلب، صفحه‌ها برای یک رویداد واحد (برای مثال، pointerdown، pointerup، و click) چندین شنونده دارند. اگر همه آن‌ها در یک قاب پویانمایی اجرا شوند، در این زمان ادغام خواهند شد. در این مورد، مدت پردازش ۲۹۵٫۶ میلی‌ثانیه طول می‌کشد که بخش عمده زمان INP است.
  • ‫presentationDelay: زمان از زمانی که شنوندگان رویداد تکمیل شده‌اند تا زمانی که مرورگر نقاشی قاب بعدی را تمام کرده است. در این مورد، ۲۱٫۴ میلی‌ثانیه.

این مراحل 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: [{...}]
}],

در اینجا تعدادی مقدار مفید وجود دارد، مانند تفکیک مقدار زمان صرف‌شده برای سبک‌دهی. مقاله «میانای برنامه‌سازی کاربردی قاب‌های پویانمایی طولانی» این دارایی‌ها را به‌طور دقیق‌تر بررسی می‌کند. درحال‌حاضر، ما بیشتر به دارایی 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 فراخوانده شده است. حتی می‌توانیم نشانی وب منبع دستورگان و موقعیت نویسه محل تعریف تابع را ببینیم!

ره‌آورد

از این داده‌های اسنادی چه چیزی درباره این پرونده می‌توان تعیین کرد؟

  • این تعامل با کلیک روی عنصر button#confirm (از attribution.interactionTarget و دارایی invoker در ورودی اسناد ارجاعی اسکریپت) راه‌اندازی شد.
  • زمان صرف‌شده عمدتاً برای اجرای شنوندگان رویداد بوده است (از attribution.processingDuration در مقایسه با سنجه کل value).
  • کد شنونده رویداد کند از شنونده کلیکی که در third-party/cmp.js (از scripts.sourceURL) تعریف شده است شروع می‌شود.

این داده‌ها برای اینکه بدانیم کجا باید بهینه‌سازی کنیم کافی است!

‫۶. چندین شنونده رویداد

صفحه را بازآوری کنید تا کنسول DevTools پاک شود و تعامل موافقت با کوکی دیگر طولانی‌ترین تعامل نباشد.

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

داده‌های اسنادی

ابتدا، یک اسکن سطح بالا از یک نمونه آزمایش نسخه نمایشی:

{
  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 به‌دست آمده است. بیشتر زمان—۱۰۶۱ میلی‌ثانیه از مجموع ۱۰۷۲ میلی‌ثانیه INP—صرف مدت پردازش شد.

بااین‌حال، 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. این زمان صرف‌شده در فراخوانی این دستورگان است که در آن مرورگر مجبور به بازچیدمان صفحه شده است. به‌عبارت دیگر، ۷۸٪ از زمان—۳۸۸ میلی‌ثانیه از ۴۹۷—صرف اجرای این شنونده رویداد درواقع صرف درهم‌ریختگی چیدمان شده است.

این باید در اولویت بالای رفع قرار گیرد.

شنوندگان تکراری

به‌صورت جداگانه، هیچ چیز قابل‌توجهی درباره دو ورودی بعدی متن وجود ندارد:

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 گزارش نمی‌شود)، اما همچنان فایل منبع و موقعیت نویسه را داریم، بنابراین می‌توانیم مکان کد را پیدا کنیم.

نکته عجیب این است که هر دو از یک فایل منبع و موقعیت نویسه هستند.

مرورگر درنهایت چندین فشار کلید را در یک قاب پویانمایی پردازش کرد که باعث شد این شنونده رویداد قبل‌از اینکه چیزی بتواند نقاشی شود، دو بار اجرا شود!

این اثر می‌تواند مرکب نیز باشد، به این معنی که هرچه تکمیل شنوندگان رویداد بیشتر طول بکشد، رویدادهای ورودی اضافی بیشتری می‌توانند وارد شوند و تعامل کند را طولانی‌تر کنند.

ازآنجایی‌که این یک تعامل جستجو/تکمیل خودکار است، استفاده از استراتژی «لرزش‌گیری» برای ورودی می‌تواند مفید باشد تا در هر قاب، حداکثر یک فشار کلید پردازش شود.

‫۷. تأخیر ورودی

دلیل معمول تأخیرهای ورودی—فاصله زمانی بین تعامل کاربر و زمانی که شنونده رویداد می‌تواند پردازش تعامل را شروع کند—این است که رشته اصلی مشغول است. این مشکل می‌تواند دلایل متعددی داشته باشد:

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

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

  • برای شروع پویانمایی، روی نشان‌واره حلزون کلیک کنید.
  • تکالیف جاوا اسکریپت زمانی فعال می‌شوند که حلزون در پایین جهش قرار دارد. سعی کنید تا حد امکان نزدیک به پایین جهش با صفحه تعامل داشته باشید و ببینید چه مقدار 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: [{...}]
    }]
  }
}

همان‌طور که پیش‌بینی می‌شد، شنوندگان رویداد به‌سرعت اجرا شدند و مدت پردازش ۴٫۹ میلی‌ثانیه را نشان دادند، و بخش عمده تعامل ضعیف در تأخیر ورودی صرف شد و ۷۰۲٫۳ میلی‌ثانیه از مجموع ۷۲۸ میلی‌ثانیه را به‌خود اختصاص داد.

اشکال‌زدایی این وضعیت می‌تواند دشوار باشد. اگرچه می‌دانیم کاربر با چه چیزی و چگونه تعامل داشته است، اما می‌دانیم که آن بخش از تعامل به‌سرعت تکمیل شده است و مشکلی نداشته است. درعوض، چیز دیگری در صفحه باعث تأخیر در شروع پردازش تعامل شده بود، اما چگونه می‌توانیم بفهمیم از کجا باید شروع به جستجو کنیم؟

ورودی‌های دستورگان 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)، دقیقاً کدام عملکرد مسئول بوده است، و در کجای فایل‌های منبع ما قرار داشته است.

‫۸. تأخیر در ارائه: زمانی که یک به‌روزرسانی رنگ‌آمیزی نمی‌شود

تأخیر در ارائه، مدت زمانی را اندازه‌گیری می‌کند که از پایان اجرای شنوندگان رویداد تا زمانی که مرورگر بتواند قاب جدیدی را در صفحه نقاشی کند و بازخورد قابل‌مشاهده را به کاربر نشان دهد، طول می‌کشد.

صفحه را بازآوری کنید تا مقدار 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 تماس برگشتی است.

‫۹. نتیجه‌گیری

درحال تجمیع داده‌های فیلد

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

برای مثال، دانستن اینکه کدام عنصر صفحه منبع مشترک تعاملات کند است بسیار مفید است. بااین‌حال، اگر صفحه شما نام‌های کلاس CSS گردآوری‌شده‌ای داشته باشد که از ساخت به ساخت تغییر می‌کنند، web-vitals گزینشگرهای عنصر یکسان ممکن است در ساخت‌های مختلف متفاوت باشند.

درعوض، باید به برنامه خاص خودتان فکر کنید تا تعیین کنید چه چیزی مفیدتر است و چگونه می‌توان داده‌ها را تجمیع کرد. برای مثال، قبل‌از ارسال داده‌های اسنادی با چراغ راهنما، می‌توانید گزینشگر web-vitals را با شناسه خودتان براساس مؤلفه‌ای که هدف در آن قرار دارد یا نقش‌های ARIA که هدف برآورده می‌کند جایگزین کنید.

به‌همین ترتیب، ورودی‌های scripts ممکن است در مسیرهای sourceURL خود دارای درهم‌سازی‌های مبتنی بر فایل باشند که ترکیب آن‌ها را دشوار می‌کند، اما می‌توانید درهم‌سازی‌ها را براساس فرایند ساخت شناخته‌شده خود قبل‌از ارسال داده‌ها ازطریق چراغ راهنما حذف کنید.

متأسفانه، با چنین داده‌های پیچیده‌ای مسیر آسانی وجود ندارد، اما حتی استفاده از زیرمجموعه‌ای از آن برای فرایند اشکال‌زدایی ارزشمندتر از نداشتن داده‌های اسنادی است.

ارجاع در همه‌جا!

اسناد خطایابی مبتنی بر LoAF کمک قدرتمندی برای اشکال‌زدایی است. این گزارش داده‌های جزئی درباره آنچه به‌طور دقیق درطول یک INP رخ داده است ارائه می‌دهد. در بسیاری از موارد، می‌تواند شما را به مکان دقیق در یک دستورگان راهنمایی کند که باید تلاش‌های بهینه‌سازی خود را از آنجا شروع کنید.

اکنون آماده‌اید از داده‌های اسنادی INP در هر سایتی استفاده کنید!

حتی اگر دسترسی به ویرایش صفحه نداشته باشید، می‌توانید با اجرای تکه‌کد زیر در کنسول DevTools، فرایند را از این کدآزمایی بازآفرینی کنید تا ببینید چه چیزی می‌توانید پیدا کنید:

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);

بیشتر بدانید