Bundle analiz — @next/bundle-analyzer
Muammodan boshlaylik
npm run build natijasi:
Route (app) Size First Load JS
┌ ○ / 5.2 kB 312 kB
├ ○ /katalog 8.1 kB 318 kB
└ ƒ /mahsulot/[id] 42 kB 352 kB
+ First Load JS shared by all 306 kB
306 KB umumiy JavaScript — har bir sahifada. Arzon telefonda bu yuklab olish, parse va bajarish uchun bir necha soniya. Qaysi kutubxona aybdor? moment.js? Butun lodash? Ikonka to'plami?
Taxmin qilish o'rniga — ko'rish kerak.
Hayotiy o'xshatma
Sayohat chamadoni juda og'ir. Hammasini to'kib, polga yoyib chiqasiz — va 3 ta ortiqcha kurtka, hech qachon o'qilmaydigan kitob va ikkita fen topasiz. Bundle analyzer — chamadonni polga yoyish.
Build natijasini o'qish
| Ustun | Ma'nosi |
|---|---|
| Size | Faqat shu sahifaga xos JavaScript |
| First Load JS | Sahifa birinchi ochilganda yuklanadigan jami JS (umumiy + xos) |
○ |
Statik |
● |
SSG (generateStaticParams) |
ƒ |
Dinamik (har so'rovda server render) |
Taxminiy mo'ljal: First Load JS ~100–150 KB atrofida bo'lsa — yaxshi; 300 KB+ — tekshirish kerak.
O'rnatish
npm install -D @next/bundle-analyzer
// next.config.ts
import type { NextConfig } from 'next'
import withBundleAnalyzer from '@next/bundle-analyzer'
const nextConfig: NextConfig = {
// ...
}
export default withBundleAnalyzer({
enabled: process.env.ANALYZE === 'true',
})(nextConfig)
ANALYZE=true npm run build
# Windows PowerShell: $env:ANALYZE="true"; npm run build
Brauzerda uchta hisobot ochiladi: client, nodejs (server), edge. Asosiysi — client: foydalanuvchiga ketadigan kod.
[!INFO]
@next/bundle-analyzerwebpack build bilan ishlaydi. Agar build Turbopack bilan bajarilsa, analiz uchun webpack build ni ishga tushiring (next build --webpack, Next.js 16) yoki o'z versiyangiz hujjatidagi Turbopack analizatorini tekshiring.
Hisobotni o'qish
To'rtburchaklar xaritasi (treemap): har bir to'rtburchak — modul, o'lchami — hajmi.
Qidiring:
- Katta to'rtburchaklar — og'ir kutubxonalar
- Takrorlanishlar — bitta kutubxonaning ikki versiyasi
- Kutilmagan narsalar — server kutubxonasi client da (masalan,
prismayoki butunzodlokallari)
Tipik aybdorlar va yechimlar
| Muammo | Hajm (taxminan) | Yechim |
|---|---|---|
moment + barcha lokallar |
~300 KB | date-fns, dayjs yoki Intl.DateTimeFormat |
Butun lodash |
~70 KB | lodash-es dan alohida funksiya yoki o'z kodingiz |
| Butun ikonka to'plami | yuzlab KB | Faqat kerakli ikonkalar import |
| Grafik kutubxonasi har sahifada | ~200 KB | dynamic import — faqat kerakli sahifada (56-dars) |
| Markdown/kod ajratish client da | ~150 KB | Server Component da render |
'use client' daraxtning yuqorisida |
— | Client chegarasini pastga tushirish |
Import usuli muhim
// ❌ — ba'zi kutubxonalarda butun to'plam keladi
import { debounce } from 'lodash'
// ✅
import debounce from 'lodash/debounce'
Next.js ko'p mashhur kutubxonalar uchun bu muammoni o'zi hal qiladi:
// next.config.ts
const nextConfig = {
experimental: {
optimizePackageImports: ['lucide-react', 'date-fns', '@heroicons/react'],
},
}
optimizePackageImports — "barrel" fayllardan faqat ishlatilgan modullarni oladi. Ko'p kutubxonalar (lucide-react, date-fns, lodash-es...) uchun allaqachon standart holatda yoqilgan.
Eng kuchli usul — server da qoldirish
// ❌ — Client Component: markdown parser brauzerga ketadi
'use client'
import { marked } from 'marked'
export function Maqola({ md }: { md: string }) {
return <div dangerouslySetInnerHTML={{ __html: marked(md) }} />
}
// ✅ — Server Component: parser serverda qoladi, brauzerga faqat HTML
import { marked } from 'marked'
export async function Maqola({ md }: { md: string }) {
return <div dangerouslySetInnerHTML={{ __html: await marked(md) }} />
}
Server Component da ishlatilgan kutubxonalar client bundle ga tushmaydi — 0 KB.
[!WARNING] Foydalanuvchi kiritgan markdown dan HTML yasasangiz — uni tozalang (DOMPurify yoki
sanitize-html), aks holda XSS. Yuqoridagi misol faqat o'zingiz yozgan kontent uchun.
server-only
// lib/db.ts
import 'server-only'
Bu fayl tasodifan Client Component ga import qilinsa — build xatosi. Server kodining (va maxfiy kalitlarning) brauzerga sizib chiqishidan himoya.
Muntazam nazorat
[!TIP] Bundle hajmini CI da kuzating: har bir Pull Request da build natijasini oldingisi bilan solishtiring (
size-limit, Vercel ning build tahlili yoki GitHub Action). "Bitta kutubxona qo'shdim" degan o'zgarish sezilmasdan 200 KB qo'shishi mumkin.
Tez-tez uchraydigan xatolar
1. Faqat "Size" ga qarash
Sahifa 5 KB — lekin First Load JS 350 KB. Umumiy (shared) qismni ham tekshiring.
2. Server kutubxonasini client ga import qilish
import { prisma } from '@/lib/prisma' Client Component da — xato yoki ulkan bundle. server-only.
3. Development da o'lchash
Development build siqilmagan va qo'shimcha kodga ega. Faqat npm run build natijasi.
Xulosa
npm run build — Size va First Load JS; ○ statik, ƒ dinamik
@next/bundle-analyzer: ANALYZE=true npm run build → treemap
Katta kutubxonalar: moment, lodash, ikonkalar, grafiklar
Yechimlar: yengil muqobil, aniq import, optimizePackageImports, dynamic import
Server Component — kutubxona brauzerga tushmaydi
server-only — server kodini himoyalash
CI da bundle hajmini kuzatish
Keyingi dars
56-dars: Dynamic Import — komponentlarni bo'laklash
Og'ir komponentlarni faqat kerak bo'lganda yuklash.