
کامپوننت Image یکی از قدرتمندترین ابزارهای Next.js برای بهینهسازی تصاویر است، اما خیلی از توسعهدهندهها فقط با چند prop پایهای آن مثل src و alt آشنا هستند و از قابلیتهای واقعیاش مثل کنترل دقیق روی lazy loading، placeholder، و کیفیت خروجی استفاده نمیکنند. در این مقاله تمام props کاربردی این کامپوننت را با مثالهای عملی بررسی میکنیم تا بتوانید تصاویر پروژهتان را هم از نظر عملکرد و هم از نظر تجربه کاربری بهینه کنید.
نکته مهم: این مقاله بر اساس Next.js 16 نوشته شده. اگر از نسخههای قدیمیتر استفاده میکنید، به بخش مربوط به preload توجه ویژه داشته باشید چون یک تغییر مهم در آن رخ داده است.
هر Image حداقل به دو prop نیاز دارد:
import Image from 'next/image'
export default function Page() {
return (
<Image
src="/profile.png"
width={
src میتواند سه نوع مقدار بگیرد:
/profile.pngremotePatterns تنظیمات next.config.js مجاز شده باشد)import profile from './profile.png')alt برای دسترسپذیری (accessibility) و سئو الزامی است. متن آن باید توصیفی و معنادار باشد، نه صرفاً تکرار کپشن اطراف تصویر. اگر تصویر کاملاً تزئینی است، مقدار آن را رشته خالی alt="" بگذارید.
این دو مقدار، ابعاد ذاتی (intrinsic) تصویر را مشخص میکنند تا مرورگر بتواند از همان ابتدا فضای لازم را رزرو کند و از Layout Shift جلوگیری شود. دقت کنید که این دو مقدار، اندازه نمایشی نهایی تصویر را تعیین نمیکنند؛ آن کار بر عهده CSS است.
تنظیم width و height الزامی است مگر در دو حالت:
fill استفاده کنیداگر نمیدانید ابعاد دقیق تصویر چقدر است، یا میخواهید تصویر کل فضای والد را پر کند، از fill استفاده کنید:
<div style={{ position: 'relative', width: '400px', height: '300px' }}>
<Image
src="/mountains.jpg"
alt="منظره کوهستان"
fill
style={{ objectFit: 'cover' }}
/>
</div>نکته حیاتی: والد این تصویر باید position: relative (یا fixed/absolute) داشته باشد، وگرنه تصویر به شکل درستی رندر نمیشود. برای کنترل نحوه جایگیری تصویر داخل کانتینر هم از objectFit: 'cover' یا objectFit: 'contain' استفاده کنید.
وقتی از fill استفاده میکنید یا تصویر با CSS واکنشگرا شده، باید sizes را هم مشخص کنید. بدون آن، مرورگر فرض میکند تصویر به اندازه کل viewport است و ممکن است فایل بزرگتری از حد نیاز دانلود شود.
<Image
fill
src="/example.png"
alt="نمونه تصویر واکنشگرا"
sizes="(max-width: 768px) 100vw, (max-width: 1200px) 50vw, 33vw"
/>وقتی sizes را تعریف میکنید، Next.js یک srcset کاملتر (مثلاً 640w، 750w و ...) تولید میکند که برای layoutهای واکنشگرا مناسبتر است. بدون sizes، فقط srcset محدودی (مثل 1x و 2x) ساخته میشود که برای تصاویر با اندازه ثابت کافی است.
مقداری بین ۱ تا ۱۰۰ که کیفیت خروجی تصویر بهینهشده را کنترل میکند. مقدار پیشفرض ۷۵ است:
<Image quality={80} src="/profile.png" width={500} height={500} alt="..." />اگر در next.config.js مقدار qualities را محدود کرده باشید، عدد وارد شده باید دقیقاً با یکی از مقادیر مجاز مطابقت داشته باشد؛ در غیر این صورت نزدیکترین مقدار مجاز استفاده میشود.
این یکی از مهمترین تغییراتی است که خیلی از منابع آموزشی هنوز آن را پوشش ندادهاند. تا قبل از Next.js 16، برای تصاویری که در بخش Largest Contentful Paint (LCP) صفحه قرار داشتند (مثلاً تصویر hero بالای صفحه)، از prop به نام priority استفاده میشد. از نسخه ۱۶ به بعد، این prop منسوخ (deprecated) شده و به جای آن باید از preload استفاده کنید:
<Image
src="/hero.jpg"
alt="تصویر اصلی صفحه"
width={1200}
height={600}
preload
/>وقتی preload={true} باشد، یک تگ <link> در <head> صفحه درج میشود تا مرورگر بارگذاری تصویر را زودتر شروع کند. از این prop فقط برای تصویری استفاده کنید که واقعاً عنصر LCP صفحه است؛ استفاده بیرویه از آن روی چند تصویر همزمان، مزیت عملکردیاش را از بین میبرد. اگر صفحهتان چند تصویر دارد که هرکدام بسته به viewport میتوانند LCP باشند، بهجای preload بهتر است از loading="eager" یا fetchPriority="high" استفاده کنید.
برای بهبود حس بارگذاری صفحه، میتوانید یک placeholder موقت نمایش دهید:
<Image
src="/profile.png"
alt="تصویر پروفایل"
width={500}
height={500}
placeholder="blur"
blurDataURL="data:image/jpeg;base64,..."
/>سه حالت برای placeholder وجود دارد:
empty: بدون placeholder (پیشفرض)blur: نمایش نسخه محو شده تصویر، که باید همراه با blurDataURL استفاده شوداگر تصویر را با ایمپورت استاتیک (فرمت jpg، png، webp یا avif) وارد کرده باشید، blurDataURL بهصورت خودکار تولید میشود. برای تصاویر ریموت یا داینامیک باید خودتان آن را بسازید، مثلاً با ابزارهایی مثل Plaiceholder.
برای اعمال استایل مستقیم روی تصویر:
<Image
src="/avatar.png"
alt="آواتار کاربر"
width={100}
height={100}
style={{ borderRadius: '50%', border: '1px solid #eee' }}
/>نکته مهم: اگر با style عرض تصویر را تغییر میدهید، حتماً height: 'auto' را هم اضافه کنید تا نسبت ابعاد تصویر حفظ شود.
<Image src="/photo.jpg" alt="..." width={800} height={600} loading="eager" />مقدار پیشفرض lazy است و تصویر تا زمانی که به viewport نزدیک نشود بارگذاری نمیشود. مقدار eager باعث بارگذاری فوری تصویر میشود؛ این را فقط برای تصاویری استفاده کنید که واقعاً باید بلافاصله لود شوند.
این دو callback به شما اجازه میدهند به رویدادهای بارگذاری تصویر واکنش نشان دهید:
'use client'
<Image
src="/photo.jpg"
alt="..."
width={800}
height={600}
onLoad={(e) => console.log('بارگذاری کامل شد', e.target.naturalWidth)}
onError={() => console.error('بارگذاری تصویر ناموفق بود')}
/>نکته: چون این props تابع میگیرند، کامپوننتی که آنها را استفاده میکند باید Client Component باشد.
برخی تصاویر، مثل فایلهای SVG، تصاویر متحرک (GIF) یا فایلهای خیلی کوچک، از بهینهسازی Next.js سودی نمیبرند. در این موارد:
<Image src="/icon.svg" alt="آیکون" width={24} height={24} unoptimized />برای استفاده از تصاویر خارجی، باید هاست آنها را در next.config.js مجاز کنید:
module.exports = {
images: {
remotePatterns: [
{
protocol: 'https',
hostname: 'example.com',
pathname: '/account123/**',
},
],
},
}بدون این تنظیم، درخواست به تصویر خارجی با خطای 400 مواجه میشود. این محدودیت برای جلوگیری از سوءاستفاده در Image Optimization API طراحی شده است.
sizes روی تصاویر با fill، که باعث دانلود فایلهای بزرگتر از حد نیاز میشودpreload روی چند تصویر همزمان، در حالی که فقط یک تصویر LCP واقعی وجود داردstyle بدون تنظیم height: 'auto'unoptimized برای SVG یا تصاویر خیلی کوچک
کامپوننت Image در Next.js فراتر از یک <img> ساده است. با ترکیب درست props مثل sizes، preload، placeholder و quality، میتوانید هم Core Web Vitals پروژهتان را بهبود دهید و هم تجربه کاربری بهتری ارائه کنید. اگر روی Next.js 16 یا بالاتر کار میکنید، حتماً priority را با preload جایگزین کنید تا از هشدارهای deprecation در آینده جلوگیری کنید.