بهینهسازی تصویر در Next.js: از LCP کند تا لود زیر یک ثانیه
نویسنده: آرش لطیفی
راهنمای عملی بهینهسازی تصویر در Next.js با next/image، فرمتهای مدرن، سایزبندی درست و کش هوشمند برای بهبود LCP و Core Web Vitals.
خلاصه: بیشتر کندی سایتهای Next.js از تصویر است نه کد. با
next/imageدرست،sizesدقیق، فرمتAVIF/WebPو کش مناسب، میتوانLCPرا از ۳ ثانیه به زیر ۱.۵ ثانیه آورد بدون افت کیفیت.
چرا تصویر گلوگاه است
یک هدر ۲۵۰۰ پیکسلی با فرمت JPEG قدیمی بهراحتی ۸۰۰ کیلوبایت میشود. روی اینترنت موبایل ایران همین یک فایل LCP را خراب میکند. next/image بهصورت خودکار ریسایز، فرمت مدرن و lazy-load میدهد، اما اگر sizes و priority را اشتباه بدهی، مرورگر باز هم تصویر بزرگ را دانلود میکند. بهینهسازی یعنی به مرورگر بگویی دقیقا چه سایزی نیاز دارد.
اگر سایتت با مشکل سرعت کلی درگیر است، اول راهنمای سرعت و Core Web Vitals را ببین؛ اینجا فقط لایه تصویر را عمیق میکنیم.
تنظیم درست next/image
سه قانون ساده:
۱. ابعاد واقعی بده، layout را رها کن. از width و height واقعی استفاده کن تا CLS صفر بماند.
۲. sizes را دقیق بنویس. مقدار پیشفرض 100vw یعنی مرورگر همیشه بزرگترین نسخه را میگیرد.
۳. فقط تصویر LCP را priority کن. بقیه باید lazy بمانند.
| الگو | چه میکند | کی استفاده کنی |
| --- | --- | --- |
| priority + fetchPriority="high" | لود سریع هیرو | فقط یک تصویر بالای فولد |
| sizes="(max-width: 768px) 100vw, 50vw" | سایز درست به مرورگر | کارتهای دو ستونه |
| placeholder="blur" | جلوگیری از پرش لayout | لیست محصولات |
برای کارت محصول که در دسکتاپ نصف صفحه است، sizes اشتباه میتواند ۳ برابر ترافیک اضافه بسازد.
فرمت مدرن و سایز هوشمند
در next.config.js فرمتها را فعال کن. AVIF کوچکتر است، WebP سازگاری بیشتر. Next.js بهصورت خودکار بهترین را انتخاب میکند.
نکته ایرانی: هاست داخل ایران گاهی AVIF را کش نمیکند. هدر Cache-Control را چک کن و اگر CDN نداری، حداقل images.domains یا remotePatterns را درست بگذار تا ریسایز از مبدا انجام شود. برای عکسهای ریموت از تامینکننده، حتما remotePatterns را محدود به دامنه اصلی کن.
مرتبط: اگر پروژهات تازه به Tailwind v4 مهاجرت کرده، مطمئن شو content شامل مسیر تصاویر است تا کلاسهای aspect-ratio حذف نشوند.
کش، CDN و لود تنبل
تصویر بهینه بدون کش فایده ندارد. سه لایه کش را چک کن:
- مرورگر: Next.js بهصورت پیشفرض
Cache-Control: public, max-age=31536000, immutableبرای تصاویر بهینه میگذارد. - CDN: اگر از Cloudflare یا Arvan استفاده میکنی،
Tiered Cacheرا روشن کن تا ریسایز تکراری نشود. - ساختار صفحه: تصاویر زیر فولد را
loading="lazy"بگذار و هرگز به همهpriorityنده؛ این اشتباه رایجLCPرا بدتر میکند.
برای دیباگ، تب Network را با Disable cache خاموش تست کن و ستون Content-Type را ببین که واقعا avif برگشته یا نه. اگر هنوز jpeg میبینی، formats فعال نیست یا Accept هدر مرورگر قدیمی است.
برای فرمها و اعتبارسنجی که معمولا بعد از لود تصویر اجرا میشود، اعتبارسنجی فرم با Zod را ببین تا hydration سنگین، LCP را عقب نیندازد.
چکلیست بهینهسازی تصویر
- [ ] فقط یک تصویر هیرو
priorityدارد، بقیهlazyهستند - [ ] همه
Imageهاwidth/heightواقعی وsizesدقیق دارند - [ ]
formats: ["image/avif", "image/webp"]درnext.config.jsفعال است - [ ]
placeholder="blur"برای کارتها و لیست محصولات فعال است - [ ]
remotePatternsفقط به دامنههای ضروری محدود شده - [ ] کش CDN و هدر
Cache-Controlبرای/_next/imageبررسی شد - [ ] تست Lighthouse روی موبایل:
LCPزیر ۲.۵ ثانیه وCLSزیر ۰.۱
FAQ
آیا همه تصاویر را AVIF کنم؟
خیر. بگذار Next.js انتخاب کند. تو فقط formats را فعال کن و quality را روی ۷۵ تا ۸۵ نگه دار. تبدیل دستی معمولا کیفیت را خراب میکند.
چرا با next/image باز هم LCP بالاست؟
سه دلیل شایع: priority روی تصویر اشتباه، sizes="100vw" برای کارت کوچک، یا هیروی پسزمینه با CSS background-image بهجای Image. هیرو را با Image و priority بساز.
تصاویر ریموت از پنل تامینکننده کند است، چه کنم؟
remotePatterns را محدود کن، deviceSizes را کم کن و اگر ممکن است تصاویر پرفروش را لوکال کن. ریسایز ریموت هر بار به مبدا میرود و اگر سرور تامینکننده کند باشد، TTFB تصویر بالا میماند.