IlmHamroh
JavaScript Full-stack/23-qism. Next.js31/43-dars17 daqiqa
Mundarija (35)

next/image: rasmni avtomatik o'lchamlash, sizes, preload va CLS

Qisqacha: <Image> (next/image) — <img> ning aqlli o'rinbosari. U bitta rasmdan turli kenglikdagi variantlar (srcset) va WebP formatini serverda yasaydi. Rasm o'lchami (width/height) bilan joy ajratib CLS'ning oldini oladi va rasmni sukut bo'yicha kech (lazy) yuklaydi. sizes — brauzerga rasm ekranda qancha joy egallashini aytadi. LCP rasmi uchun Next 16 da priority o'rniga preload. Tashqi domendagi rasm — faqat next.config dagi remotePatterns ga yozilgan bo'lsa.

Bu darsda

  • <Image> qanday srcset yasashini va brauzer qaysi kenglikni tanlashini kanondagi haqiqiy o'lchov bilan ko'rasiz.
  • sizes ni to'g'ri yozasiz va u bo'lmasa nima bo'lishini bilasiz.
  • width/height siz rasm production'da jim CLS beradigan bo'lishini haqiqiy tajribada ko'rasiz.
  • LCP rasmiga preload qo'yasiz va o'lchangan farqni o'qiysiz.
  • Proxy matcher sababli telefonda rasm ko'rinmay qolgan haqiqiy xatoning to'liq hikoyasini bilasiz.

Oldin bilishingiz kerak: Responsive rasmlar: srcset va sizes, Core Web Vitals, proxy.ts, Rendering strategiyalari.

1. Nega bu kerak?

portfolio ning case study sahifasida loyiha skrinshoti bor: public/loyihalar/vazifalar.png, 1280×800, 18 408 bayt PNG. Oddiy <img> bilan nima bo'lardi?

  • Telefon (375 px ekran) ham 1280 pikselli rasmni yuklaydi — kerakli kenglikdan ko'p.
  • PNG — skrinshot uchun yaxshi, lekin WebP bir necha marta yengil.
  • width/height unutilsa — rasm yuklanganda matn pastga sakraydi (CLS, Cumulative Layout Shift — "joylashuv siljishi", Core Web Vitals).

Responsive rasmlar va Rasm unumdorligi darslarida bularni qo'lda yechgansiz: rasmni 3 o'lchamda eksport qilish, <picture>, srcset, sizes. To'g'ri, lekin har rasm uchun qo'lda ish. next/image buni avtomatlashtiradi: siz bitta fayl qo'yasiz, variantlarni server yasaydi.

Hayotiy o'xshatish: tikuvchi. Oddiy <img> — tayyor kiyim do'koni: bitta o'lcham hammaga. next/image — tikuvchi: har mijozga o'lchab tikadi, ortiqcha mato ishlatmaydi.

2. <Image> nima yasaydi

2.1 Kanondagi kod

Case study sahifasi (holat 32):

tsx
<Image
  src={loyiha.rasm.fayl}
  alt={loyiha.rasm.alt}
  width={loyiha.rasm.eni}
  height={loyiha.rasm.boyi}
  sizes="(width < 70ch) 100vw, 70ch"
  preload
/>
Prop Qiymat Nima uchun
src /loyihalar/vazifalar.png public/ dagi asl fayl
alt "Vazifalar ilovasi: ro'yxat, …" ekran o'quvchi uchun (alt matn)
width, height 1280, 800 nisbat — joy oldindan ajratiladi
sizes (width < 70ch) 100vw, 70ch tor ekranda butun kenglik, keng ekranda 70 belgi
preload — LCP rasmi — <head> da oldindan yuklash

2.2 Haqiqiy HTML

Shu komponent serverda qanday <img> ga aylanadi (holat 32 nusxasi, next start, biz ishga tushirdik; srcSet qisqartirildi — har variant bir xil ko'rinishda):

text
<img alt="Vazifalar ilovasi: ro&#x27;yxat, filtrlar va qo&#x27;shish formasi" width="1280" height="800" decoding="async" data-nimg="1" style="color:transparent" sizes="(width &lt; 70ch) 100vw, 70ch" srcSet="/_next/image?url=%2Floyihalar%2Fvazifalar.png&amp;w=640&amp;q=75 640w, … w=3840&amp;q=75 3840w" src="/_next/image?url=%2Floyihalar%2Fvazifalar.png&amp;w=3840&amp;q=75"/>

Uch narsa:

  1. srcSet dagi har manzil — /_next/image?url=…&w=…&q=75: Next'ning rasm optimizatori (image optimizer). U so'rov kelganda asl PNG'ni kerakli kenglikka kichraytiradi, WebP qiladi va keshlaydi.
  2. Kengliklar: 640, 750, 828, 1080, 1200, 1920, 2048, 3840 — Next'ning deviceSizes ro'yxati.
  3. q=75 — sifat. Next 16 da sukut bo'yicha faqat 75 ruxsat: boshqa sifat kerak bo'lsa, next.config dagi images.qualities ga yoziladi. Hujjat sababini aytadi: aks holda hujumchi har xil sifatlarni so'rab serverni band qilardi.

2.3 Optimizator javoblari

Kanon har kenglikni curl bilan so'radi (natijalar/32-next-image.txt):

text
w=640 200 image/webp 6924 B 0.329132s
w=750 200 image/webp 8336 B 0.110688s
w=828 200 image/webp 9014 B 0.141127s
w=1080 200 image/webp 12252 B 0.167530s
w=1200 200 image/webp 13774 B 0.222174s
w=1920 200 image/webp 14564 B 0.217980s
w=3840 200 image/webp 14564 B 0.217686s
/loyihalar/vazifalar.png 200 image/png 18408
vazifalar.png: asl fayl va optimizator variantlari
  • asl PNG1280×80018 408 B
  • WebP w=6406 924 B
  • WebP w=750telefon, DPR 28 336 B
  • WebP w=120013 774 B
  • WebP w=1920asl 1280 dan katta qilinmaydi14 564 B

Manba: IlmHamroh kanoni, portfolio holat 32, next 16.4.0, curl, 2026-10-21 (natijalar/32-next-image.txt)

Telefon variantini (w=750) yuklagan foydalanuvchi asl fayldan 2.2 marta kam bayt oladi. Oxirgi ikki qator bir xil: 1920 va 3840 so'ralganda ham 14 564 bayt — optimizator rasmni asl 1280 dan kattalashtirmaydi.

3. Brauzer qaysi kenglikni tanlaydi

3.1 sizes bilan

srcSet — menyu, tanlovni brauzer qiladi. U ikki narsaga qaraydi: sizes (rasm ekranda necha piksel) va ekranning piksel zichligi (DPR, device pixel ratio — bitta CSS pikselda nechta haqiqiy piksel; zamonaviy telefonlarda 2–3).

Kanon o'lchovi (natijalar/32-rasm-keyin.txt):

Ekran sizes natijasi × DPR Tanlangan
Mobil 375, DPR 2 100vw = 375 750 w=750
Desktop 1280, DPR 1 70ch ≈ 600 ~600 w=640

Ya'ni brauzer "kerakli kenglikdan katta, eng kichik variant" ni oladi. 70ch — 70 belgi kengligi, matn ustunining kengligi bilan bir xil (O'lcham birliklari).

3.2 Natija oynasida: kengliklar ro'yxati

Next srcSet ni qanday yasashini kichik model bilan takrorlaymiz. Bu Next kodining soddalashtirilgan nusxasi (mantiq — getWidths funksiyasidan), natijasi esa yuqoridagi haqiqiy HTML va quyidagi tajriba bilan bir xil:

js
const deviceSizes = [640, 750, 828, 1080, 1200, 1920, 2048, 3840];
const imageSizes = [32, 48, 64, 96, 128, 256, 384];
const hammasi = [...imageSizes, ...deviceSizes];

function kengliklar(width, sizes) {
  if (sizes) {
    const foizlar = [...sizes.matchAll(/(\d+)vw/g)].map((m) => +m[1]);
    const nisbat = Math.min(...foizlar) / 100;
    return hammasi.filter((w) => w >= deviceSizes[0] * nisbat);
  }
  // sizes yo'q: 1x va 2x — eng yaqin katta variant
  const top = (k) => hammasi.find((w) => w >= k) ?? hammasi.at(-1);
  return [top(width), top(width * 2)];
}

console.log(kengliklar(1280, "(width < 70ch) 100vw, 70ch").join(" "));
console.log(kengliklar(1280).join(" "));
console.log(kengliklar(96, "(width < 600px) 50vw, 96px").join(" "));

Konsolda:

text
640 750 828 1080 1200 1920 2048 3840
1920 3840
384 640 750 828 1080 1200 1920 2048 3840

Birinchi qator — kanondagi srcSet aynan. Ikkinchi — sizes siz: Next faqat ikki variant beradi (1x, 2x). Biz buni haqiqiy next dev da ham ko'rdik — sizes siz rasm uchun: w=1920 1x, w=3840 2x. Uchinchi qatorda 50vw — rasm yarim ekran, shuning uchun kichikroq imageSizes dan ham boshlanadi.

sizes siz katta rasmning narxi: telefon 1x deb 1920 lik variantni oladi — kerakdan 2.5 marta ko'p. Qoida: ekranning bir qismini egallaydigan har rasmga sizes yozing.

Tekshirib ko'ring: Avatar rasmi doim 48×48 CSS piksel. sizes kerakmi?

Javob

Kerak emas. Kichik, o'lchami o'zgarmaydigan rasm uchun width={48} height={48} yetarli: Next 1x va 2x (48 va 96 dan katta eng yaqin variantlar) beradi. sizes — kengligi ekranga bog'liq (vw) rasmlar uchun.

4. width va height — CLS'ga qarshi

4.1 Biz sinadik: width siz

<Image src="/loyihalar/vazifalar.png" alt="Vazifalar" /> — width va height siz. Tip tekshiruvi o'tdi (width turida ixtiyoriy — statik import va fill uchun). Natija ikki xil (biz ishga tushirdik, next 16.4.0):

next dev da sahifa 500 va xato:

text
⨯ Error: Image with src "/loyihalar/vazifalar.png" is missing required "width" property.

next build esa o'tdi va production'da <img> shunday chiqdi:

text
<img alt="Vazifalar" loading="lazy" decoding="async" data-nimg="1" style="color:transparent" sizes="100vw" srcSet="…" src="/_next/image?url=%2Floyihalar%2Fvazifalar.png&amp;w=3840&amp;q=75"/>

width ham, height ham yo'q. Brauzer rasm yuklanmaguncha uning balandligini bilmaydi — joy 0, keyin rasm kelib matnni pastga suradi. Bu CLS. Xato faqat dev'da qichqiradi, production'da jim — root layout darsidagi <html> siz layout bilan bir xil saboq: dev'dagi qizil oynani e'tiborsiz qoldirmang.

4.2 Statik import — o'lcham o'zi

Rasmni import qilsangiz, Next o'lchamni build'da o'zi o'qiydi:

tsx
import rasm from "@/../public/loyihalar/vazifalar.png";

<Image src={rasm} alt="Vazifalar" placeholder="blur" />

next dev da natija (biz ishga tushirdik, qisqartirilgan):

text
<img alt="Vazifalar" width="1280" height="800" … style="…background-image:url(&quot;data:image/svg+xml;…data:image/png;base64,iVBORw0KGgo…&quot;)" srcSet="/_next/image?url=%2F_next%2Fstatic%2Fmedia%2Fvazifalar.288_l_ambzv4c.png&amp;w=1920&amp;q=75 1x, …&amp;w=3840&amp;q=75 2x"/>

width="1280" height="800" — o'zi qo'shildi. placeholder="blur" — rasm yuklanguncha fon sifatida 8×5 piksellik xira nusxa (base64, HTML ichida). Fayl /_next/static/media/vazifalar.288_l_ambzv4c.png ga ko'chdi — nomida xesh, ya'ni abadiy keshlanadi.

Kanon nega statik import emas, public/ + qo'lda width/height ishlatadi? Loyihalar ro'yxati — oddiy ma'lumot (LOYIHALAR): sitemap, OG va metadata ham undan rasm manzilini oladi. O'lcham ma'lumot ichida (eni, boyi).

4.3 fill — o'lcham ota elementdan

Rasm o'lchami oldindan noma'lum bo'lsa (masalan, kartochka fonida), fill: rasm ota elementni to'liq egallaydi. Ota element position: relative va aniq o'lchamli bo'lishi shart, sizes ham kerak:

tsx
<div style={{ position: "relative", aspectRatio: "16 / 10" }}>
  <Image
    src={rasm}
    alt="…"
    fill
    sizes="(width < 640px) 100vw, 50vw"
  />
</div>

object-fit: cover bilan rasm qirqiladi, nisbat saqlanadi.

5. LCP rasmi va preload

5.1 Lazy — sukut

<Image> sukut bo'yicha loading="lazy": rasm ekranga yaqinlashgandagina yuklanadi. Pastdagi rasmlar uchun bu juda yaxshi. Lekin LCP elementi (ekrandagi eng katta element) rasm bo'lsa, lazy uni kechiktiradi.

Kanon o'lchadi: desktop'da case study rasmi — LCP elementi. Next 16 da buning uchun preload (priority eskirgan — hujjat: "Next 16 dan priority preload foydasiga eskirgan"). preload HTML <head> ga shunday qator qo'shadi (holat 32 nusxasi, next start, biz ishga tushirdik; o'rtadagi variantlar … bilan qisqartirildi):

text
<link rel="preload" as="image" imageSrcSet="/_next/image?url=%2Floyihalar%2Fvazifalar.png&amp;w=640&amp;q=75 640w, /_next/image?url=%2Floyihalar%2Fvazifalar.png…&amp;q=75 3840w" imageSizes="(width &lt; 70ch) 100vw, 70ch"/>

va <img> dan loading="lazy" olib tashlanadi. Brauzer rasmni HTML'ni oxirigacha o'qishni kutmasdan boshlaydi. Hujjat qo'shimcha qiladi: ko'p hollarda loading="eager" yoki fetchPriority="high" ham yetarli; preload ni ular bilan birga yozmang.

5.2 O'lchov — oldin va keyin

Kanon preload dan oldin va keyin Chrome'da o'lchadi (32-rasm-oldin.txt, 32-rasm-keyin.txt):

Mobil 375 (DPR 2) Desktop 1280
Oldin LCP <p> 752 ms, rasm w=750 404 LCP IMG 412 ms (lazy), w=640 6 924 B
Keyin LCP IMG 908 ms, w=750 webp 8 336 B LCP IMG 396 ms
CLS 0 0

Desktop'da 412 → 396 ms — kichik, lekin to'g'ri yo'nalishda. Mobil qatordagi raqamlar esa g'alati: "oldin" LCP elementi rasm emas, paragraf — va rasm 404. "Keyin" LCP kattaroq (908 ms), lekin endi rasm ko'rinadi va u eng katta element. Ya'ni mobil raqamlarni solishtirib bo'lmaydi: "oldin" holatda rasm umuman yo'q edi. Nega? Keyingi bo'lim — shu haqda.

6. Biz topdik: telefonda rasm yo'q edi

6.1 Belgi

32-rasm-oldin.txt dan mobil qism:

text
## mobil (375px): LCP {"t":752,"el":"PKundalik vazifalarni"}, CLS 0.0000
img: {"currentSrc":"3127/_next/image?url=%2Floyihalar%2Fvazifalar.png&w=750&q=75","loading":"lazy","fetchpriority":null,"sizes":"(width < 70ch) 100vw, 70ch"}
  image /_next/image?url=%2Floyihalar%2Fvazifalar.png&w=750&q=75 undefined 57 B

Brauzer to'g'ri variantni so'radi (w=750), lekin javob — 57 bayt, turi undefined. Bu rasm emas — xato javobi. Optimizatorni to'g'ridan so'raganda: 404 "url parameter is valid but internal response is invalid" ("manzil parametri to'g'ri, lekin ichki javob yaroqsiz").

6.2 Sabab — proxy

Optimizator asl rasmni olish uchun o'z serveriga ichki so'rov yuboradi: /loyihalar/vazifalar.png. Bu so'rov ham proxy dan o'tadi. Holat 27 dagi matcher esa:

ts
matcher: [
  "/loyihalar/:slug",
  "/loyihalar/:slug/rasm",
  "/blog/:slug((?!rss\\.xml$).*)",
],

:slug — "bitta segment, istalgan belgi". vazifalar.png ham bitta segment! Proxy uni noma'lum loyiha slug'i deb hisobladi va /_topilmadi ga burdi — 404. Optimizator 404 olib, o'zi ham 404 qaytardi.

sequenceDiagram
  participant B as Brauzer (telefon)
  participant O as /_next/image
  participant P as proxy.ts
  B->>O: w=750 so'rovi
  O->>P: ichki GET /loyihalar/vazifalar.png
  P-->>O: rewrite /_topilmadi → 404
  O-->>B: 404 (57 B)

6.3 Nega besh holat davomida bilinmadi

Desktop o'lchovi doim yaxshi edi: w=640 — 6 924 B webp. Sabab — kesh. Optimizator natijalarni .next/cache/images da saqlaydi, va 640/1080 variantlari proxy qo'shilishidan oldingi build'larda yaratilib, keshda qolgan edi. Proxy ularni so'ramadi — kesh javob berdi. w=750 esa hech qachon so'ralmagan: telefon o'lchovi birinchi marta holat 32 da qilindi. Kanon .next ni tozalab qayta o'lchadi — xato hamma kenglikda chiqdi.

Tuzatish — matcher'da slug belgilarini cheklash ([a-z0-9-]+), batafsil proxy.ts darsida. Kanon holat 27 va 30 dagi proxy.ts ni ham almashtirdi. Tuzatishdan keyin — «Optimizator javoblari» bo'limidagi jadval: hamma kenglik 200.

Saboqlar:

  • Proxy hamma so'rovni ko'radi — rasm optimizatorining ichki so'rovlarini ham.
  • Kesh xatoni yashirishi mumkin: o'lchovdan oldin keshni tozalang.
  • Faqat desktop'da tekshirish yetmaydi — telefon boshqa variant so'raydi.

Tekshirib ko'ring: Proxy matcher'ga butunlay boshqa yechim: "/((?!_next/image).*)" — optimizator yo'lini istisno qilish. Bu xatoni tuzatadimi?

Javob

Yo'q. Optimizatorning o'zi proxy'dan o'tmaydi, lekin u yuboradigan ichki so'rov — /loyihalar/vazifalar.png — baribir matcher'ga tushadi. Kerakli narsa — fayl manzillarini (nuqtali yo'llarni) proxy'dan chiqarish. Hujjatdagi umumiy naqsh ham .*\\.png$ ni istisno qiladi.

7. Tashqi rasmlar va sozlamalar

7.1 remotePatterns

Boshqa domendagi rasm (masalan GitHub avatari):

tsx
<Image
  src="https://example.com/rasm.png"
  alt="…"
  width={640}
  height={400}
/>

next dev da (biz ishga tushirdik):

text
⨯ Error: Invalid src prop (https://example.com/rasm.png) on `next/image`, hostname "example.com" is not configured under images in your `next.config.js`
See more info: https://nextjs.org/docs/messages/next-image-unconfigured-host

Tarjimasi: "example.com hosti next.config.js dagi images da sozlanmagan". Bu himoya: aks holda sizning optimizatoringiz internetdagi istalgan rasmni kichraytirib berardi — boshqalar uni bepul xizmat sifatida ishlatardi. Ruxsat:

ts
// next.config.ts
images: {
  remotePatterns: [
    new URL("https://avatars.githubusercontent.com/**"),
  ],
},

Faqat kerakli host va yo'l — ** bilan butun internetni ochmang.

7.2 Boshqa sozlamalar

Sozlama Nima
images.qualities ruxsat etilgan sifatlar (Next 16 da sukut [75])
images.deviceSizes, imageSizes srcSet kengliklari
images.localPatterns public/ ning qaysi yo'llari optimizatsiya qilinadi
images.minimumCacheTTL optimizator keshining eng kam umri
loader / loaderFile optimizatsiyani tashqi CDN'ga topshirish (Cloudinary, imgix)
unoptimized optimizatsiyasiz oddiy <img> (SVG, juda kichik rasmlar)

O'z serveringizda (Vercel'siz) optimizator sharp kutubxonasini ishlatadi — zamonaviy Next versiyalarida uni alohida o'rnatish odatda shart emas (hujjat bo'yicha; biz alohida tekshirmadik). Hujjat ogohlantiradi: glibc asosli Linux tizimlarida sharp ko'p xotira yeyishi mumkin, maxsus sozlama kerak bo'ladi. output: "export" (statik eksport) da optimizator yo'q — unoptimized yoki tashqi loader.

8. Portfolio qadami: preload va matcher

8.1 O'zgarishlar (holat 32 ning bir qismi)

diff
             sizes="(width < 70ch) 100vw, 70ch"
+            // Desktop'da LCP elementi shu rasm (o'lchandi) — Next 16: priority o'rniga preload (N-31)
+            preload
           />

Va src/proxy.ts dagi matcher — [a-z0-9-]+ bilan (proxy darsida qilgan bo'lsangiz — tayyor).

8.2 Tekshiruv

bash
rm -rf .next
npm run build
npm run start

.next ni tozalash — ataylab: eski keshlangan rasm variantlari xatoni yashirmasin. DevTools'da telefon rejimini yoqing (375 px), case study sahifasini oching va Network panelida _next/image so'rovlari 200 va webp ekanini tekshiring. Kanon o'lchovi: CLS 0, JS o'zgarmadi.

Hali commit qilmang: kanonda holat 32 keyingi dars (next/font) bilan bitta commit.

9. Ko'p uchraydigan xatolar

Belgi Sabab Davosi
missing required "width" property (dev) width/height yo'q Bering yoki statik import / fill
Production'da CLS, xato yo'q Xuddi shu — prod jim Dev xatosini tuzating
hostname "…" is not configured under images Tashqi rasm, remotePatterns yo'q Aniq host bilan remotePatterns
Telefonda katta variant yuklanadi sizes yo'q sizes yozing
_next/image 404 "internal response is invalid" Proxy yoki auth asl rasm yo'lini to'sadi Matcher'dan fayl yo'llarini chiqaring
priority ogohlantirish beradi Next 16 da eskirgan preload
quality={90} ta'sir qilmaydi qualities ro'yxatida yo'q — 75 ga keltiriladi images.qualities: [75, 90]
fill rasm ko'rinmaydi ota element position: relative emas yoki balandligi 0 position: relative + o'lcham

10. Mashqlar

Mashqlar kurs/mashqlar/23/31-next-image/ da. Jonli yechimlarni «Ishga tushir» bilan sinang.

1-mashq (oson): prop tanlang

  • Ekranning birinchi qismidagi katta rasm (LCP) —
  • Kengligi ekranning yarmi — sizes qiymati:
  • O'lchami noma'lum, ota elementni to'ldiradi —
  • Rasm yuklanguncha xira nusxa — placeholder=""
Yechim
  • preload — <head> da oldindan yuklash, lazy o'chadi.
  • 50vw — viewport kengligining 50 foizi.
  • fill — width/height o'rniga; ota position: relative bilan.
  • blur — statik importda avtomatik, tashqi rasmda blurDataURL kerak.

2-mashq (o'rta): qaysi variant yuklanadi?

«kengliklar ro'yxati» blokidagi kengliklar funksiyasiga tanla(royxat, cssKenglik, dpr) qo'shing: kerakli piksel = cssKenglik × dpr, natija — ro'yxatdagi undan katta yoki teng eng kichik kenglik. Uch holatni sinang: telefon 375/DPR 2, desktop 600/DPR 1, planshet 768/DPR 2 (sizes — kanondagi).

Yechim
js
const deviceSizes = [640, 750, 828, 1080, 1200, 1920, 2048, 3840];
const imageSizes = [32, 48, 64, 96, 128, 256, 384];
const hammasi = [...imageSizes, ...deviceSizes];

function kengliklar(width, sizes) {
  if (sizes) {
    const foizlar = [...sizes.matchAll(/(\d+)vw/g)].map((m) => +m[1]);
    const nisbat = Math.min(...foizlar) / 100;
    return hammasi.filter((w) => w >= deviceSizes[0] * nisbat);
  }
  const top = (k) => hammasi.find((w) => w >= k) ?? hammasi.at(-1);
  return [top(width), top(width * 2)];
}

function tanla(royxat, cssKenglik, dpr) {
  const kerak = cssKenglik * dpr;
  return royxat.find((w) => w >= kerak) ?? royxat.at(-1);
}

const royxat = kengliklar(1280, "(width < 70ch) 100vw, 70ch");
console.log("telefon:", tanla(royxat, 375, 2));
console.log("desktop:", tanla(royxat, 600, 1));
console.log("planshet:", tanla(royxat, 768, 2));

Konsolda:

text
telefon: 750
desktop: 640
planshet: 1920

Birinchi ikkitasi kanon o'lchovi bilan bir xil (w=750 va w=640). Planshetda 768 × 2 = 1536 — undan katta eng kichigi 1920; optimizator esa asl 1280 dan kattalashtirmaydi, shuning uchun 14 564 baytli fayl keladi. Haqiqiy brauzer tanlovi biroz murakkabroq (kesh, tarmoq tezligi), lekin asosiy qoida shu.

3-mashq (qiyin): matcher rasmni ushlaydimi?

Proxy darsidagi shablonniRegex g'oyasidan foydalanib, rasmniTekshir(matcherlar, yollar) yozing: har rasm yo'li uchun — birorta matcher unga mos kelsa XAVF: yo'l, aks holda OK: yo'l. Eski va yangi matcher'larni /loyihalar/vazifalar.png, /loyihalar/bahor.png, /blog/rss.xml da sinang. some — "birortasi mos kelsa".

Yechim
js
function shablonniRegex(shablon) {
  const ichi = shablon.replace(
    /:(\w+)(\(([^)]*)\))?/g,
    (_, nom, __, re) => `(${re ?? "[^/]+"})`,
  );
  return new RegExp(`^${ichi}$`);
}

function rasmniTekshir(matcherlar, yollar) {
  const re = matcherlar.map(shablonniRegex);
  for (const y of yollar) {
    const xavf = re.some((r) => r.test(y));
    console.log(xavf ? `XAVF: ${y}` : `OK: ${y}`);
  }
}

const yollar = [
  "/loyihalar/vazifalar.png",
  "/loyihalar/bahor.png",
  "/blog/rss.xml",
];
console.log("eski:");
const eski = ["/loyihalar/:slug", "/blog/:slug((?!rss\\.xml$).*)"];
rasmniTekshir(eski, yollar);
console.log("yangi:");
rasmniTekshir(
  ["/loyihalar/:slug([a-z0-9-]+)", "/blog/:slug([a-z0-9-]+)"],
  yollar,
);

Konsolda:

text
eski:
XAVF: /loyihalar/vazifalar.png
XAVF: /loyihalar/bahor.png
OK: /blog/rss.xml
yangi:
OK: /loyihalar/vazifalar.png
OK: /loyihalar/bahor.png
OK: /blog/rss.xml

Eski matcher RSS'ni istisno bilan yopgan, lekin har bir .png ni ushlaydi. Bunday tekshiruvni test sifatida yozib qo'ysangiz, matcher o'zgarganda xato qaytib kelmaydi — kanon testlari (Next.js ilovani test qilish) shu g'oyani ishlatadi.

4-mashq: Portfolio qadami

Case study rasmiga preload qo'shing, proxy.ts matcher'i tuzatilganini tekshiring. .next ni tozalab build qiling va telefon rejimida rasm ko'rinishini, Network'da _next/image?…&w=750 200 va image/webp ekanini tasdiqlang.

Yechim

Kutilgan: w=750 — 200, image/webp, ~8 KB. Agar 404 bo'lsa — matcher hali eski. Elements panelida <head> ichida <link rel="preload" as="image" …> qatorini toping — preload ishlayotganining belgisi. Commit'ni keyingi darsdan keyin qiling.

11. Real ishda

  • E-commerce va media saytlar — next/image ning asosiy foydalanuvchilari: minglab mahsulot rasmlari, har biri telefon uchun kichraytirilgan.
  • Katta loyihalarda optimizatsiya ko'pincha tashqi xizmatga beriladi (loader — Cloudinary, imgix, Cloudflare Images): server CPU'sini tejash uchun.
  • Lighthouse "Properly size images" va "Serve images in next-gen formats" tavsiyalari — next/image to'g'ri ishlatilsa, ikkalasi ham yo'qoladi.
  • Intervyu savoli: "next/image nima qiladi?", "sizes nima uchun?", "priority (endi preload) qachon kerak?" — LCP va CLS bilan bog'lab javob bering.

Xulosa

  • <Image> bitta fayldan srcSet (640…3840) va WebP variantlarini yasaydi; vazifalar.png 18 408 B → telefonga 8 336 B.
  • sizes brauzerga rasm kengligini aytadi; u bo'lmasa — faqat 1x/2x, telefonga keragidan katta rasm.
  • width/height siz rasm dev'da xato, production'da jim CLS; statik import o'lchamni o'zi beradi.
  • LCP rasmiga preload (Next 16 da priority eskirgan); remotePatterns va qualities — himoya sozlamalari.
  • Kanon topdi: proxy matcher .png ni ushlab optimizatorni 404 qilgan, kesh esa buni yashirgan.

Keyingi dars: next/font va next/script — Rubik shriftini o'z serverimizdan yuklaymiz, OG rasmlarga ham shrift beramiz va DataView tuzog'ini ko'ramiz.

Manbalar

  • Next.js hujjati (16.4.0, node_modules/next/dist/docs/): Image component — sizes, fill, preload, priority (deprecated), qualities, remotePatterns, deviceSizes/imageSizes, minimumCacheTTL; "Self-hosting" (sharp) — nextjs.org/docs/app/api-reference/components/image (2026-10-21 da o'qildi)
  • Kanon natijalari: natijalar/32-next-image.txt, natijalar/32-rasm-oldin.txt, natijalar/32-rasm-keyin.txt (matcher xatosi — holat 32 da topilgan)
  • width siz rasm, statik import + blur, remotePatterns xatosi — biz ishga tushirdik: portfolio holat 32 nusxasi, next 16.4.0, next dev va next build/next start, 2026-10-21
  • getWidths mantiqi — next 16.4.0 manbasi (shared/lib/get-img-props)
Ulashish:Telegram'da

Izohlar (0)

Izoh yozish uchun kiring.

  • Hozircha izoh yo'q. Birinchi bo'ling!
next/image: rasmni avtomatik o'lchamlash, sizes, preload va CLS — IlmHamroh