وقتی یک سایت Premium کند است، اولین پیشنهاد معمولاً حذف Animation، ویدئو یا تصویر بزرگ است. این پاسخ سریع اما ناقص است. مشکل واقعی اغلب در Delivery اشتباه همان طراحی قرار دارد: تصویر Hero دیر کشف میشود، فونت چند بار جابهجایی ایجاد میکند، Component ساده به Bundle بزرگ Client تبدیل شده یا Script شخص ثالث Main Thread را اشغال کرده است.
Core Web Vitals سه بُعد تجربه را میسنجد: LCP سرعت نمایش محتوای اصلی، INP پاسخگویی به Interaction و CLS پایداری بصری. آستانههای «خوب» فعلی در صدک ۷۵، LCP حداکثر ۲٫۵ ثانیه، INP حداکثر ۲۰۰ میلیثانیه و CLS حداکثر ۰٫۱ هستند.
قبل از Optimization: Lab و Field را جدا کنید
Lighthouse یک اجرای کنترلشده و مناسب Debug است. CrUX و RUM تجربه کاربران واقعی با Device، Network، Cache و Interaction متفاوت را نشان میدهند. ممکن است Lighthouse خوب باشد اما INP واقعی خراب باشد؛ یا CLS پس از Scroll رخ دهد و تست اولیه آن را نبیند.
Workflow درست:
- مشکل را در Field و به تفکیک Template/Device/Route تأیید کنید.
- با PSI، DevTools trace و React Profiler علت را محدود کنید.
- یک Hypothesis بسازید و تغییر کوچک اعمال کنید.
- Regression lab را همان لحظه بررسی کنید.
- اثر Field را پس از جمعشدن داده کافی بسنجید.
LCP؛ عنصر اصلی چرا دیر دیده میشود؟
LCP فقط حجم تصویر نیست. زنجیره معمول شامل TTFB، کشف Resource، زمان Download و Render delay است.
1. TTFB و Server path
اگر Server برای چند API زنجیرهای منتظر بماند، Browser دیر HTML را میگیرد. Fetchهای مستقل را موازی کنید، Cache متناسب با Freshness تعریف کنید و عملیات غیرضروری را از Critical path خارج کنید. Dynamic rendering بدون نیاز، هزینه هر Request را بالا میبرد.
2. تصویر Hero
- از
next/imageباsizesواقعی استفاده کنید تا Browser فایل بیش از حد بزرگ نگیرد. - ابعاد را مشخص کنید.
- اگر تصویر LCP است، Lazy load نکنید و Discovery آن را به JavaScript دیرهنگام نسپارید.
- Format و Quality را با تست بصری انتخاب کنید؛ Quality بالا برای همه عرضها لازم نیست.
- CDN و Cache header را بررسی کنید.
import Image from "next/image";
<Image
src="/images/hero.webp"
alt="معماری سیستم دیجیتال ویدرا"
width={1600}
height={900}
sizes="(max-width: 768px) 100vw, 60vw"
priority
/>priority را روی چند تصویر استفاده نکنید؛ Resourceهای مهم با هم رقابت میکنند.
3. Render delay
گاهی تصویر Download شده اما Overlay، Hydration یا Animation ورودی نمایش را عقب میاندازد. عنصر LCP را به پایان یک Timeline انیمیشن وابسته نکنید. Animation میتواند پس از Paint اولیه و با Transform/Opacity اجرا شود.
INP؛ مشکل تعامل فقط Event Handler نیست
INP کل زمان از Interaction تا Paint بعدی را میسنجد: Input delay، Processing و Presentation delay. علتهای رایج:
- Bundle زیاد و Long Task در Main Thread.
- Re-render گسترده React پس از Click.
- محاسبه یا Parse سنگین در Handler.
- Third-party script.
- DOM بزرگ و Layout/Style calculation پرهزینه.
Server-first و مرز Client کوچک
در App Router، فقط Componentهای تعاملی را Client کنید. قرار دادن "use client" در Layout بالا میتواند subtree بزرگی را به Client graph ببرد. State را نزدیک محل مصرف نگه دارید و Library سنگین را برای Interaction نادر Dynamic import کنید.
کار سنگین را خرد یا منتقل کنید
Task طولانی را به بخشهای کوچک تقسیم کنید تا Browser فرصت پاسخ دهد. پردازش CPU-heavy واقعی میتواند به Web Worker یا Server منتقل شود. Debounce برای Search مفید است، اما جای الگوریتم کارآمد را نمیگیرد.
Re-render را اندازه بگیرید
Memoization کورکورانه Code را پیچیده میکند. با React Profiler مشخص کنید چه Componentهایی و چرا Render میشوند. Context بزرگ، State در سطح بالا و Object جدید در Prop از علتهای معمولاند.
CLS؛ صفحه چرا حرکت میکند؟
Media بدون ابعاد
برای Image، Video، Embed و Ad فضای از قبل رزرو کنید. Aspect ratio یا Dimension مشخص مانع تغییر Layout پس از Load میشود.
Font
next/font فونت را Self-host و Layout را قابل کنترلتر میکند، اما انتخاب Fallback نامتناسب و تعداد زیاد Weight هنوز مشکلساز است. فقط وزنهای لازم را Load و Fallback metric-compatible انتخاب کنید.
محتوای دیرهنگام بالای صفحه
Banner، Cookie notice یا پیام Validation نباید بدون فضای رزروشده محتوای موجود را پایین بزند. از Overlay مناسب یا Slot ثابت استفاده کنید.
Animation Layout-based
تغییر top/left/width/height میتواند Layout ایجاد کند. در صورت امکان Transform و Opacity بهکار ببرید؛ البته Animation زیاد همچنان میتواند GPU/CPU و Accessibility را تحت فشار قرار دهد.
Third-partyها؛ کدی که مالک آن نیستید
Analytics، Chat، Heatmap و Tag Manager ممکن است سهم بزرگی از JavaScript و Network داشته باشند. برای هر Script Owner و هدف اندازهگیری مشخص کنید. Script بدون تصمیم تجاری، بدهی Performance است.
راهکارها:
- حذف Tagهای تکراری یا بدون استفاده.
- Load براساس Consent و Intent.
- Delay ابزار غیرضروری تا پس از Interaction یا Idle.
- پایش تغییرات Vendor.
- محدودکردن تعداد Experiment همزمان.
Cache و CDN؛ سریع اما درست
Cache طولانی برای Asset hashشده مناسب است، نه برای HTML شخصی. Revalidation باید با Content update هماهنگ باشد. Cache اشتباه میتواند داده قدیمی یا حتی داده Tenant دیگر را نمایش دهد؛ Performance هرگز نباید Isolation را نقض کند.
Performance Budget از مرحله Design
Budget نمونه:
- حداکثر وزن Media بالای Fold برای Mobile.
- تعداد Font family/weight.
- JavaScript اولیه هر Route.
- تعداد Third-party connection.
- سقف Long Task و DOM size.
عدد باید براساس مخاطب و Baseline انتخاب شود. Budget باید در CI هشدار یا Gate داشته باشد؛ Document فراموششده Budget نیست.
طراحی حرفهای را چگونه حفظ کنیم؟
- Motion را برای توضیح Hierarchy و Feedback نگه دارید، نه تزئین دائمی.
- نسخه Mobile تصویر/ویدئوی سبکتر داشته باشد.
prefers-reduced-motionرا رعایت کنید.- Skeleton را با ابعاد نهایی هماهنگ کنید.
- Progressive enhancement: محتوا بدون اجرای کامل Interaction قابل فهم باشد.
- یک عنصر Hero قوی بهتر از پنج افکت همزمان است.
اشتباههای رایج
- Optimization فقط براساس Score یک اجرای Lighthouse.
- Lazy load کردن تصویر LCP.
priorityدادن به همه تصویرها.- Dynamic import کردن محتوای اصلی و دیرکرد نمایش آن.
- انتقال مشکل Server به Client با Fetch پس از Hydration.
- حذف Cache برای حل موقت Bug و فراموشکردن آن.
- نادیدهگرفتن Routeهای واقعی و تست فقط Homepage.
چکلیست عملی
LCP
- عنصر LCP در Mobile/desktop مشخص است.
- TTFB و Fetch waterfall بررسی شده است.
- Resource در HTML زود کشف و اندازه متناسب دارد.
- Animation نمایش آن را عقب نمیاندازد.
INP
- Long Task و Handler کند از Field attribution مشخص شده.
- Client boundary و Bundle بررسی شده.
- Re-render با Profiler سنجیده شده.
- Third-partyها Inventory و Owner دارند.
CLS
- Media و Embed ابعاد دارند.
- Font و Fallback تست شدهاند.
- Banner/Validation فضای رزروشده دارند.
- Shift پس از Scroll و Interaction نیز اندازهگیری شده.
جمعبندی
Core Web Vitals خوب از حذف طراحی بهدست نمیآید؛ از طراحی آگاه به Delivery حاصل میشود. ابتدا Field Data مشخص میکند کدام Template و کاربر مشکل دارد، سپس Trace علت را نشان میدهد. Next.js ابزارهای مناسبی برای Image، Font، Server rendering و Code splitting دارد، اما مرز Component، Cache و Third-party هنوز نیازمند تصمیم مهندسی است.
مسیر مطالعه مرتبط
سؤالات متداول
Core Web Vitals چیست؟
سه معیار تجربه واقعی کاربر است: LCP برای Load، INP برای Interaction و CLS برای پایداری چیدمان.
Lighthouse با Core Web Vitals واقعی چه تفاوتی دارد؟
Lighthouse Lab test است؛ Field data رفتار کاربران واقعی را جمع میکند. برای Debug از Lab و برای ارزیابی Outcome از Field استفاده کنید.
آیا `next/image` همیشه LCP را بهتر میکند؟
خیر. sizes اشتباه، Lazy load عنصر LCP یا Source دور میتواند نتیجه بدی بدهد. ابزار نیاز به پیکربندی و اندازهگیری دارد.
آیا Animation باعث افت INP میشود؟
ممکن است، بهویژه اگر Main Thread، Layout یا DOM بزرگ را درگیر کند. Transform/Opacity و Motion هدفمند معمولاً کمهزینهترند.
چرا CLS در Lighthouse صفر ولی در کاربران زیاد است؟
چون Shift ممکن است بعد از Interaction، Scroll، Banner یا Font condition رخ دهد. RUM طول عمر صفحه را بهتر پوشش میدهد.
آیا Core Web Vitals عامل رتبه است؟
Google Page Experience را در کنار سیگنالهای متعدد بررسی میکند. محتوای مفید و Intent همچنان اساسیاند؛ Performance هم برای UX و هم Search اهمیت دارد اما میانبُر رتبه نیست.
منابع رسمی و مطالعه بیشتر
Performance را با داده واقعی اصلاح کنید، نه با حذف کورکورانه طراحی
اگر طراحی سایت باید Premium بماند اما Field Data ضعف LCP، INP یا CLS نشان میدهد، حذف جلوهها بدون Root cause analysis راهحل پایدار نیست. VOIDRA میتواند مسیر Server، Bundle، Media و Interaction را اندازهگیری و Performance Budget متناسب با طراحی تعریف کند.
شروع مشاوره پروژه
