بهینه‌سازی تأخیر ورودی

با مفهوم تأخیر ورودی آشنا شوید و روش‌های کاهش آن را برای تعامل سریع‌تر یاد بگیرید.

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

تأخیر ورودی چیست؟

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

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

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

نحوه درک تأخیر ورودی

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

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

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

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

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

دو تابع زمان‌سنج پرکاربرد در جاوا اسکریپت وجود دارد که می‌توانند در تأخیر ورودی نقش داشته باشند: setTimeout و setInterval. تفاوت بین این دو این است که setTimeout زمان‌بندی می‌کند که یک فراخوانی برگشتی پس‌از زمان مشخصی اجرا شود. ازسوی‌دیگر، setInterval یک فراخوانی برگشتی را برای اجرا در هر n میلی‌ثانیه به‌طور دائم یا تا زمانی که زمان‌سنج با clearInterval متوقف شود، زمان‌بندی می‌کند.

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

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

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

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

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

اجتناب از تکالیف طولانی

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

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

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

مراقب هم‌پوشانی تعامل باشید

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

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

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

  • برای محدود کردن تعداد دفعاتی که یک فراخوانی رویداد در یک دوره زمانی مشخص اجرا می‌شود، ورودی‌های debouncing را درنظر بگیرید.
  • از AbortController برای لغو درخواست‌های fetch برون‌رفت استفاده کنید تا رشته اصلی به‌دلیل مدیریت فراخوانی‌های برگشتی fetch شلوغ نشود. توجه: از ویژگی signal نمونه AbortController نیز می‌توان برای لغو رویدادها استفاده کرد.

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

نتیجه‌گیری

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