Mundarija (35)
- Bu darsda
- 1. Nega bu kerak?
- 2. <Image> nima yasaydi
- 2.1 Kanondagi kod
- 2.2 Haqiqiy HTML
- 2.3 Optimizator javoblari
- 3. Brauzer qaysi kenglikni tanlaydi
- 3.1 sizes bilan
- 3.2 Natija oynasida: kengliklar ro'yxati
- 4. width va height — CLS'ga qarshi
- 4.1 Biz sinadik: width siz
- 4.2 Statik import — o'lcham o'zi
- 4.3 fill — o'lcham ota elementdan
- 5. LCP rasmi va preload
- 5.1 Lazy — sukut
- 5.2 O'lchov — oldin va keyin
- 6. Biz topdik: telefonda rasm yo'q edi
- 6.1 Belgi
- 6.2 Sabab — proxy
- 6.3 Nega besh holat davomida bilinmadi
- 7. Tashqi rasmlar va sozlamalar
- 7.1 remotePatterns
- 7.2 Boshqa sozlamalar
- 8. Portfolio qadami: preload va matcher
- 8.1 O'zgarishlar (holat 32 ning bir qismi)
- 8.2 Tekshiruv
- 9. Ko'p uchraydigan xatolar
- 10. Mashqlar
- 1-mashq (oson): prop tanlang
- 2-mashq (o'rta): qaysi variant yuklanadi?
- 3-mashq (qiyin): matcher rasmni ushlaydimi?
- 4-mashq: Portfolio qadami
- 11. Real ishda
- Xulosa
- Manbalar
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 dapriorityo'rnigapreload. Tashqi domendagi rasm — faqatnext.configdagiremotePatternsga yozilgan bo'lsa.
Bu darsda
<Image>qandaysrcsetyasashini va brauzer qaysi kenglikni tanlashini kanondagi haqiqiy o'lchov bilan ko'rasiz.sizesni to'g'ri yozasiz va u bo'lmasa nima bo'lishini bilasiz.width/heightsiz rasm production'da jim CLS beradigan bo'lishini haqiqiy tajribada ko'rasiz.- LCP rasmiga
preloadqo'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/heightunutilsa — 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):
<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):
<img alt="Vazifalar ilovasi: ro'yxat, filtrlar va qo'shish formasi" width="1280" height="800" decoding="async" data-nimg="1" style="color:transparent" sizes="(width < 70ch) 100vw, 70ch" srcSet="/_next/image?url=%2Floyihalar%2Fvazifalar.png&w=640&q=75 640w, … w=3840&q=75 3840w" src="/_next/image?url=%2Floyihalar%2Fvazifalar.png&w=3840&q=75"/>Uch narsa:
srcSetdagi 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.- Kengliklar: 640, 750, 828, 1080, 1200, 1920, 2048, 3840 — Next'ning
deviceSizesro'yxati. q=75— sifat. Next 16 da sukut bo'yicha faqat 75 ruxsat: boshqa sifat kerak bo'lsa,next.configdagiimages.qualitiesga 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):
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- 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:
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:
640 750 828 1080 1200 1920 2048 3840
1920 3840
384 640 750 828 1080 1200 1920 2048 3840Birinchi 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.
sizeskerakmi?
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:
⨯ Error: Image with src "/loyihalar/vazifalar.png" is missing required "width" property.next build esa o'tdi va production'da <img> shunday chiqdi:
<img alt="Vazifalar" loading="lazy" decoding="async" data-nimg="1" style="color:transparent" sizes="100vw" srcSet="…" src="/_next/image?url=%2Floyihalar%2Fvazifalar.png&w=3840&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:
import rasm from "@/../public/loyihalar/vazifalar.png";
<Image src={rasm} alt="Vazifalar" placeholder="blur" />next dev da natija (biz ishga tushirdik, qisqartirilgan):
<img alt="Vazifalar" width="1280" height="800" … style="…background-image:url("data:image/svg+xml;…data:image/png;base64,iVBORw0KGgo…")" srcSet="/_next/image?url=%2F_next%2Fstatic%2Fmedia%2Fvazifalar.288_l_ambzv4c.png&w=1920&q=75 1x, …&w=3840&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:
<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):
<link rel="preload" as="image" imageSrcSet="/_next/image?url=%2Floyihalar%2Fvazifalar.png&w=640&q=75 640w, /_next/image?url=%2Floyihalar%2Fvazifalar.png…&q=75 3840w" imageSizes="(width < 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:
## 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 BBrauzer 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:
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):
<Image
src="https://example.com/rasm.png"
alt="…"
width={640}
height={400}
/>next dev da (biz ishga tushirdik):
⨯ 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-hostTarjimasi: "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:
// 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)
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
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 —
sizesqiymati: - 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/heighto'rniga; otaposition: relativebilan. - blur — statik importda avtomatik, tashqi rasmda
blurDataURLkerak.
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
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:
telefon: 750
desktop: 640
planshet: 1920Birinchi 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
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:
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.xmlEski 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/imagening 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/imageto'g'ri ishlatilsa, ikkalasi ham yo'qoladi. - Intervyu savoli: "
next/imagenima qiladi?", "sizesnima uchun?", "priority(endipreload) qachon kerak?" — LCP va CLS bilan bog'lab javob bering.
Xulosa
<Image>bitta fayldansrcSet(640…3840) va WebP variantlarini yasaydi;vazifalar.png18 408 B → telefonga 8 336 B.sizesbrauzerga rasm kengligini aytadi; u bo'lmasa — faqat 1x/2x, telefonga keragidan katta rasm.width/heightsiz rasm dev'da xato, production'da jim CLS; statik import o'lchamni o'zi beradi.- LCP rasmiga
preload(Next 16 dapriorityeskirgan);remotePatternsvaqualities— himoya sozlamalari. - Kanon topdi: proxy matcher
.pngni 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/):Imagecomponent — 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) widthsiz rasm, statik import + blur,remotePatternsxatosi — biz ishga tushirdik:portfolioholat 32 nusxasi, next 16.4.0,next devvanext build/next start, 2026-10-21getWidthsmantiqi — next 16.4.0 manbasi (shared/lib/get-img-props)
Izohlar (0)
Izoh yozish uchun kiring.
- Hozircha izoh yo'q. Birinchi bo'ling!