Image komponenti — optimizatsiya, lazy loading, placeholder

~15 daq · Next.js · Kirish va Asoslar

Muammodan boshlaylik

Siz saytga rasm qo'ydingiz:

<img src="/hero.jpg" alt="Hero rasm" />

Ishlaydi. Lekin bir kuni Google PageSpeed Insights da tekshirasiz — ball past. Sabablari:

  • Rasm juda katta — 4000×3000px rasm, lekin ekranda 800×600px ko'rinadi. 3 MB yuklanadi, 500 KB yetardi
  • Format eski — JPEG ishlatilmoqda, WebP 30% kichikroq bo'lardi
  • Lazy loading yo'q — sahifa ochilganda ekranda ko'rinmaydigan rasmlar ham yuklanadi
  • Layout shift — rasm yuklanguncha joy ajratilmagan, kontent sakrab ketadi

Bularning hammasini qo'lda hal qilish mumkin, lekin har bir rasm uchun alohida. Next.js Image komponenti bularni avtomatik hal qiladi.


Image komponenti

import Image from 'next/image'

export default function Page() {
  return (
    <Image
      src="/hero.jpg"
      alt="Hero rasm"
      width={800}
      height={600}
    />
  )
}

Ko'rinishda oddiy. Lekin ichida Next.js:

  • Rasmni WebP formatiga aylantiradi (brauzer qo'llab-quvvatlasa)
  • Ekran o'lchamiga qarab kichiklashtiradi
  • Lazy loading qo'shadi — faqat ko'rinadigan rasmlar yuklanadi
  • width va height dan joy ajratadi — layout shift bo'lmaydi

width va height nima uchun shart

<img> da o'lcham ko'rsatmasangiz — brauzer rasm yuklanguncha qancha joy kerakligini bilmaydi. Rasm kelganda kontent sakrab ketadi. Bu Cumulative Layout Shift (CLS) — Google ranking uchun muhim metrika.

Image da width va height shart — Next.js joy oldindan ajratadi, kontent siljimaydi.

// ❌ — layout shift bo'ladi
<img src="/photo.jpg" alt="Rasm" />

// ✅ — joy oldindan ajratiladi
<Image src="/photo.jpg" alt="Rasm" width={400} height={300} />

fill — konteyner o'lchamini olish

Ba'zan rasmning aniq o'lchami ma'lum emas — masalan, foydalanuvchi yuklagan rasm. Yoki rasm konteynerga to'liq to'lishi kerak.

Buning uchun fill prop ishlatiladi. Rasm ota elementning o'lchamini oladi:

<div style={{ position: 'relative', width: '100%', height: '400px' }}>
  <Image
    src="/banner.jpg"
    alt="Banner"
    fill
    style={{ objectFit: 'cover' }}
  />
</div>

⚠️ fill ishlatilganda ota element position: relative bo'lishi shart. Aks holda rasm noto'g'ri joylashadi.

objectFit: 'cover' — rasm nisbatini saqlab, konteynerga to'liq to'ldiradi (qirqilishi mumkin). objectFit: 'contain' — rasm to'liq ko'rinadi, bo'sh joy qolishi mumkin.


priority — muhim rasmlar

Lazy loading yaxshi — lekin ba'zan rasm darhol yuklanishi kerak. Masalan, sahifaning yuqorisidagi hero rasm — foydalanuvchi sahifani ochganda birinchi ko'radigan narsa.

<Image
  src="/hero.jpg"
  alt="Hero"
  width={1200}
  height={600}
  priority   // ← darhol yuklanadi, lazy loading o'chiriladi
/>

priority — rasmni <head> da preload sifatida belgilaydi. Brauzer boshqa narsalardan oldin shu rasmni yuklaydi.

💡 Faqat sahifaning yuqorisidagi (above the fold) rasmlar uchun priority ishlating. Hamma rasmga qo'ysangiz — hech birining ahamiyati qolmaydi.


placeholder — yuklanish vaqtida

Rasm yuklanayotganda bo'sh joy ko'rinadi. placeholder prop bilan yuklanish vaqtida nimadir ko'rsatish mumkin:

// Xira (blur) effekt
<Image
  src="/photo.jpg"
  alt="Rasm"
  width={400}
  height={300}
  placeholder="blur"
  blurDataURL="data:image/jpeg;base64,/9j/4AAQ..."
/>

blurDataURL — rasmning juda kichik (10×10px) base64 versiyasi. Yuklanayotganda xira ko'rinadi, keyin to'liq rasm keladi.

Mahalliy rasmlar uchun Next.js blurDataURL ni avtomatik yaratadi:

import photo from '/public/photo.jpg'  // mahalliy rasm

<Image
  src={photo}
  alt="Rasm"
  placeholder="blur"  // blurDataURL avtomatik
/>

Tashqi rasmlar

Tashqi URL dan rasm ishlatish uchun next.config.ts da domenni ro'yxatdan o'tkazish kerak. Bu xavfsizlik uchun — ixtiyoriy saytdan rasm yuklanmasin:

// next.config.ts
const nextConfig = {
  images: {
    remotePatterns: [
      {
        protocol: 'https',
        hostname: 'images.unsplash.com',
      },
      {
        protocol: 'https',
        hostname: 'avatars.githubusercontent.com',
      },
    ],
  },
}

export default nextConfig
// Endi tashqi rasm ishlatish mumkin
<Image
  src="https://images.unsplash.com/photo-123"
  alt="Unsplash rasm"
  width={800}
  height={600}
/>

Tez-tez uchraydigan xatolar

1. fill da ota elementda position: relative yo'q

// ❌ — rasm noto'g'ri joylashadi
<div style={{ height: '400px' }}>
  <Image src="/img.jpg" alt="" fill />
</div>

// ✅
<div style={{ position: 'relative', height: '400px' }}>
  <Image src="/img.jpg" alt="" fill />
</div>

2. Tashqi rasm domenini next.config.ts da ro'yxatdan o'tkazmaslik

Error: Invalid src prop on `next/image`, hostname "images.unsplash.com"
is not configured under images in your `next.config.js`

Yechim — yuqoridagi remotePatterns ga domenni qo'shish.

3. Hamma rasmga priority qo'shish

// ❌ — hamma rasm bir vaqtda yuklanadi, sahifa sekinlashadi
<Image src="/img1.jpg" priority ... />
<Image src="/img2.jpg" priority ... />
<Image src="/img3.jpg" priority ... />

Faqat birinchi ko'rinadigan (hero, banner) rasmga priority.


Xulosa

Image — <img> ning aqlli versiyasi. Avtomatik: WebP konvertatsiya, o'lcham optimallashtirish, lazy loading, layout shift oldini olish.

width + height  → joy oldindan ajratiladi, layout shift yo'q
fill            → konteyner o'lchamini oladi, ota: position:relative
priority        → darhol yuklanadi, faqat hero/banner uchun
placeholder     → yuklanayotganda blur effekt
remotePatterns  → tashqi domenlarni ruxsatlash

Keyingi dars

8-dars: Font optimizatsiya — next/font, Google Fonts, mahalliy shriftlar

Shriftlar ham rasmlar kabi sayt tezligiga ta'sir qiladi. next/font buni qanday hal qilishini ko'ramiz.