Bundle analiz — @next/bundle-analyzer

~15 daq · Next.js · Performance va Optimizatsiya

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-analyzer webpack 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, prisma yoki butun zod lokallari)

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.