هندبوک بهینهسازی Web Vitals با تمرکز روی INP
از اندازهگیری میدانی تا شکستن long task، کاهش کار اصلی thread و بهبود پاسخدهی تعامل در اپهای React/Next.
علی مرتضوی
بنیانگذار پارادایس کد
INP جای FID را گرفت چون واقعیت تعامل را بهتر میسنجد
INP تأخیر پاسخ در طول عمر صفحه را نگاه میکند، نه فقط اولین کلیک. کاربر ممکن است LCP خوب ببیند و بعد از باز کردن فیلتر یا منو، UI یخ بزند—همان جایی که رتبه تجربه و تبدیل میریزد. پس بهینهسازی «لود اولیه» بدون پاسخدهی تعامل ناقص است.
هدف مهندسی: p75 میدانی INP را زیر آستانهٔ خوب نگه دارید، مخصوصاً روی موبایلهای میانرده که CPU محدود دارند.
اندازهگیری میدانی قبل از بهینهسازی آزمایشگاهی
Lighthouse مفید است اما کافی نیست. RUM با attribution—چه event، چه element، چه long task—مسیر درست را نشان میدهد. صفحهٔ کند در lab ممکن است در field خوب باشد یا برعکس؛ تصمیم را با CrUX/RUM بگیرید.
برای هر مسیر پولساز یک داشبورد vitals جدا داشته باشید. میانگین کل سایت مشکلات checkout را پنهان میکند.
شکستن long task روی main thread
تعامل وقتی میمیرد که main thread با هیدراسیون، parse بزرگ، یا محاسبات همگام مشغول است. کار را خرد کنید: `scheduler.yield`/setTimeout صفر، پردازش تکهای لیست، و انتقال کار سنگین به Worker وقتی امکان دارد. در React، از hydrate کردن کل درخت در یک قاب بپرهیزید.
کتابخانههای سنگین را پشت intent کاربر لود کنید—ادیتور، نقشه، نمودار—نه در bundle اولیه. import پویا باید با UX انتظار هماهنگ باشد، نه فقط با code split.
ورودی، handler و بهروزرسانی UI
Handler باید سبک باشد: اعتبارسنجیMinimal، بهروزرسانی فوری UI خوشبینانه، و کار شبکه/سنگین بعداً. debounce برای input پرتکرار، و اجتناب از re-render وسیع با state خیلی بالا در درخت. اگر یک کلیک سه context را میلرزاند، مرز state اشتباه است.
برای لیستهای بزرگ، مجازیسازی و کلید پایدار ضروری است. انیمیشن را روی `transform`/`opacity` نگه دارید تا layout thrash نسازد.
LCP و CLS را همزمان خراب نکنید
بهبود INP با تأخیر انداختن تصویر hero میتواند LCP را قربانی کند. اولویتبندی منابع را صریح کنید: `fetchpriority` برای LCP image، preload فونت بحرانی با اندازهٔ مشخص برای جلوگیری از CLS، و رزرو فضا برای بنرها و دکمهها.
فونت و تبلیغات شخص ثالث کلاسیکترین قاتلان CLSاند. اگر third-party لازم است، در کانتینر با ابعاد ثابت و بعد از تعامل یا idle لود شود.
بودجه جاوااسکریپت و فرهنگ تیم
برای مسیرهای کلیدی بودجه KB و long-task بگذارید و در CI بشکنید. بدون سقف، هر فیچر «فقط یک کتابخانه» اضافه میکند تا INP بمیرد. بودجه باید مالکی داشته باشد—مثل مالک محصول برای مسیر.
بهینهسازی عملکرد یک پروژهٔ انتهایی نیست؛ بخشی از طراحی فیچر است. اگر تعامل تازه long task جدید میآورد، همان PR باید جبران کند.
سؤالات متداول
چه آستانهای برای INP خوب است؟
طبق راهنمای فعلی Web Vitals، p75 زیر ۲۰۰ میلیثانیه خوب، تا ۵۰۰ نیاز به بهبود، و بالاتر ضعیف محسوب میشود. موبایل را جدا ببینید.
آیا کاهش bundle همیشه INP را درست میکند؟
اغلب کمک میکند، اما handler سنگین و re-render وسیع هم INP را خراب میکنند. attribution را بخوانید نه فقط اندازه bundle.
React Server Components به INP کمک میکند؟
با کاهش JS کلاینت و هیدراسیون، بله—به شرطی که Client boundaryها دوباره متورم نشوند.
third-party را چطور مدیریت کنیم؟
با تگ منیجر بیقید بارگذاری نکنید. هر اسکریپت owner، trigger، و بودجه داشته باشد؛ غیرضروریها را بعد از idle یا رضایت بارگذاری کنید.
دانش و مقالات
نیاز به اجرای همین مفاهیم در محصولتان دارید؟
پارادایس کد از مشاوره تا پیادهسازی کامل کنار شماست.