بهینه‌سازی «تأخیر در تعامل‌ها»

با نحوه بهینه‌سازی Interaction to Next Paint (‏INP) وب‌سایتتان آشنا شوید.

تاریخ انتشار: ۱۹ مه ۲۰۲۳، آخرین به‌روزرسانی: ۲ سپتامبر ۲۰۲۵

تعامل تا ترسیم بعدی (INP) یک سنجه پایدار از «هسته‌های حیاتی وب» است که پاسخ‌گویی کلی صفحه به تعامل‌های کاربر را با مشاهده تأخیر همه تعامل‌های واجدشرایط که درطول مدت بازدید کاربر از صفحه رخ می‌دهد ارزیابی می‌کند. مقدار نهایی INP طولانی‌ترین تعامل مشاهده‌شده است (گاهی‌اوقات داده‌های پرت نادیده گرفته می‌شود).

برای ارائه تجربه کاربری خوب، وب‌سایت‌ها باید تلاش کنند که «تعامل با رنگ بعدی» ۲۰۰ میلی‌ثانیه یا کمتر باشد. برای رسیدن به این هدف برای اکثر کاربران، آستانه خوب برای اندازه‌گیری صدک ۷۵ بار شدن صفحه‌ها است که در دستگاه‌های همراه و رایانه بخش‌بندی شده است.

مقادیر خوب INP برابر با ۲۰۰ میلی‌ثانیه یا کمتر است، مقادیر ضعیف بیشتر از ۵۰۰ میلی‌ثانیه است، و هر مقداری بین این دو باید بهبود یابد.
آستانه‌های INP

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

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

تشخیص علت INP ضعیف

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

پیدا کردن تعامل‌های کند در فیلد

در حالت ایده‌آل، سفر شما در بهینه‌سازی INP با داده‌های میدانی آغاز می‌شود. در بهترین حالت، داده‌های میدانی از ارائه‌دهنده «پایش کاربر واقعی» (RUM) نه‌تنها مقدار INP صفحه را به شما می‌دهد، بلکه داده‌های زمینه‌ای را نیز ارائه می‌دهد که نشان می‌دهد کدام تعامل خاص مسئول مقدار INP بوده است، آیا تعامل درطول یا پس‌از بارگیری صفحه رخ داده است، نوع تعامل (کلیک، فشردن کلید، یا ضربه زدن)، و سایر اطلاعات ارزشمند را نیز ارائه می‌دهد.

اگر برای دریافت داده‌های فیلد به ارائه‌دهنده RUM متکی نیستید، راهنمای داده‌های فیلد INP توصیه می‌کند از PageSpeed Insights برای مشاهده داده‌های «گزارش تجربه کاربری Chrome» (CrUX) استفاده کنید تا به پر کردن شکاف‌ها کمک کند. CrUX مجموعه داده Google از برنامه «معیارهای کلیدی اصلی وب» است و خلاصه‌ای سطح بالا از سنجه‌ها را برای میلیون‌ها وب‌سایت، ازجمله INP، ارائه می‌دهد. بااین‌حال، CrUX اغلب داده‌های زمینه‌ای را که از ارائه‌دهنده RUM دریافت می‌کنید ارائه نمی‌دهد تا به شما در تجزیه‌وتحلیل مشکلات کمک کند. به همین دلیل، همچنان توصیه می‌کنیم که سایت‌ها درصورت امکان از ارائه‌دهنده RUM استفاده کنند یا راهکار RUM خودشان را برای تکمیل آنچه در CrUX دردسترس است پیاده‌سازی کنند.

عیب‌یابی تعاملات کند در آزمایشگاه

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

بهینه‌سازی تعامل‌ها

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

تعامل‌ها را می‌توان به سه بخش فرعی تقسیم کرد:

  1. تأخیر ورودی که از زمانی شروع می‌شود که کاربر تعاملی را با صفحه آغاز می‌کند و زمانی پایان می‌یابد که فراخوانی‌های برگشتی رویداد برای تعامل شروع به اجرا می‌کنند.
  2. مدت پردازش، که شامل مدت‌زمانی است که طول می‌کشد تا فراخوانی‌های رویداد به‌طور کامل اجرا شوند.
  3. تأخیر ارائه، یعنی مدت زمانی که طول می‌کشد تا مرورگر فریم بعدی را که حاوی نتیجه بصری تعامل است ارائه دهد.
نمونه‌ای از تعامل در رشته اصلی. کاربر درحین اجرای تکالیف مسدودکننده، ورودی ارائه می‌دهد. ورودی تا زمان تکمیل آن تکالیف به‌تأخیر می‌افتد، پس‌از آن گرداننده‌های رویداد pointerup،‏ mouseup، و click اجرا می‌شوند، سپس کار پردازش و رنگ‌آمیزی تا زمان ارائه فریم بعدی آغاز می‌شود.
چرخه عمر تعامل. تأخیر ورودی تا زمانی که گرداننده‌های رویداد شروع به اجرا کنند رخ می‌دهد، که احتمالاً ناشی از عواملی مانند کارهای طولانی در رشته اصلی است. سپس فراخوانی‌های برگشتی کنترل‌کننده رویداد تعامل اجرا می‌شوند و قبل‌از ارائه فریم بعدی، تأخیری رخ می‌دهد.

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

شناسایی و کاهش تأخیر ورودی

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

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

رابطه بین ارزیابی اسکریپت و تکالیف طولانی درطول راه‌اندازی

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

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

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

بهینه‌سازی کردن فراخوانی‌های برگشتی رویداد

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

اغلب به رشته اصلی واگذار کنید

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

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

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

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

Yield to allow rendering work to occur sooner

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

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

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

  1. چارگوش نوشتاری را با آنچه کاربر تایپ کرده است به‌روز کنید و هر قالب‌بندی لازم را اعمال کنید.
  2. بخشی از میانای کاربری را که تعداد واژه‌های فعلی را نمایش می‌دهد به‌روز کنید.
  3. اجرای منطق برای بررسی اشتباهات املایی.
  4. جدیدترین تغییرات را ذخیره کنید (به‌صورت محلی یا در پایگاه داده راه دور).

کد انجام این کار ممکن است چیزی شبیه به کد زیر باشد:

textBox.addEventListener('input', (inputEvent) => {
  // Update the UI immediately, so the changes the user made
  // are visible as soon as the next frame is presented.
  updateTextBox(inputEvent);

  // Use `setTimeout` to defer all other work until at least the next
  // frame by queuing a task in a `requestAnimationFrame()` callback.
  requestAnimationFrame(() => {
    setTimeout(() => {
      const text = textBox.textContent;
      updateWordCount(text);
      checkSpelling(text);
      saveChanges(text);
    }, 0);
  });
});

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

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

اگرچه استفاده از setTimeout() در تماس requestAnimationFrame() در مثال کد قبلی کمی مبهم است، اما روش مؤثری است که در همه مرورگرها کار می‌کند تا از مسدود شدن فریم بعدی توسط کد غیربحرانی جلوگیری کند.

اجتناب از کوبش چیدمان

کوبش چیدمان (که گاهی چیدمان همگام اجباری نامیده می‌شود) مشکلی در عملکرد پرداز زدن است که در آن چیدمان به‌صورت همگام رخ می‌دهد. این مشکل زمانی رخ می‌دهد که سبک‌ها را در جاوا اسکریپت به‌روزرسانی می‌کنید و سپس آن‌ها را در همان وظیفه می‌خوانید—و ویژگی‌های زیادی در جاوا اسکریپت وجود دارد که می‌تواند باعث کوبش چیدمان شود.

تجسمی از کوبش چیدمان همان‌طور که در پانل عملکرد Chrome DevTools نشان داده شده است.
نمونه‌ای از کوبش چیدمان، همان‌طور که در پانل عملکرد Chrome DevTools نشان داده شده است. تکالیف پردازشی که شامل کوبش چیدمان هستند با یک مثلث قرمز در گوشه بالا سمت راست بخشی از پشته فراخوانی مشخص می‌شوند که اغلب با برچسب Recalculate Style (محاسبه مجدد سبک) یا Layout (چیدمان) نشان داده می‌شوند.

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

به حداقل رساندن تأخیر ارائه

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

کوچک کردن اندازه DOM

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

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

به‌خاطر داشته باشید که در برخی موارد، DOMهای بزرگ را نمی‌توان به‌طور قابل‌توجهی کاهش داد. اگرچه رویکردهایی وجود دارد که می‌توانید برای کاهش اندازه DOM اتخاذ کنید، مانند مسطح کردن DOM یا افزودن به DOM درطول تعاملات کاربر برای کوچک نگه داشتن اندازه اولیه DOM، این تکنیک‌ها ممکن است فقط تا حدودی مؤثر باشند.

از content-visibility برای رندر کردن تنبل عناصر خارج از صفحه استفاده کنید

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

هنگام ارائه HTML بااستفاده از جاوا اسکریپت، از هزینه‌های عملکرد آگاه باشید

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

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

درحالی‌که اولین بازدید از هر وب‌سایت همیشه شامل مقداری HTML است، یک رویکرد رایج با مقدار اولیه حداقلی HTML شروع می‌شود و سپس از جاوا اسکریپت برای پر کردن ناحیه محتوا استفاده می‌شود. به‌روزرسانی‌های بعدی در آن ناحیه محتوا نیز درنتیجه تعاملات کاربر رخ می‌دهد. این معمولاً مدل برنامه تک‌صفحه‌ای (SPA) نامیده می‌شود. یکی از معایب این الگو این است که با ارائه HTML با JavaScript در کلاینت، نه‌تنها هزینه پردازش JavaScript برای ایجاد آن HTML را دریافت می‌کنید، بلکه مرورگر تا زمانی که تجزیه آن HTML و ارائه آن را تمام نکند، تسلیم نخواهد شد.

بااین‌حال، یادآوری این نکته حیاتی است که حتی وب‌سایت‌هایی که SPA نیستند احتمالاً درنتیجه تعاملات، مقداری پردازش HTML ازطریق JavaScript خواهند داشت. این کار معمولاً مشکلی ندارد، به‌شرطی که مقدار زیادی HTML را در کلاینت رندر نکنید، زیرا این کار می‌تواند ارائه فریم بعدی را به‌تأخیر بیندازد. بااین‌حال، مهم است که پیامدهای عملکردی این رویکرد برای ارائه HTML در مرورگر را درک کنید و بدانید که اگر HTML زیادی را بااستفاده از جاوا اسکریپت ارائه می‌دهید، چگونه می‌تواند بر پاسخ‌گویی وب‌سایت شما به ورودی کاربر تأثیر بگذارد.

نتیجه‌گیری

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

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