Bundle Size — tahlil qilish, optimizatsiya
Muammodan boshlaylik
npm run build:
dist/assets/index-8f3a2c.js 1,240.55 kB │ gzip: 398.12 kB
Ilovangizda 20 ta sahifa bor, lekin siz o'zingiz yozgan kod — taxminan 150 KB. Qolgan 1 MB — qayerdan?
Javob odatda kutilmagan: bitta sana formatlash uchun butun moment.js (barcha tillar bilan), bitta funksiya uchun butun lodash, ikonka kutubxonasining 3000 ta ikonkasi, bir marta ishlatilgan grafiklar kutubxonasi...
JavaScript ning har bir kilobayti foydalanuvchi uchun uch marta qimmat: uni yuklash, tahlil qilish (parse) va bajarish kerak. O'rtacha telefonda 400 KB gzip li JavaScript — bir necha soniyalik kechikish.
1-qadam: tahlil
Avval — nima joy egallayotganini ko'rish kerak.
npx vite-bundle-visualizer
Brauzerda interaktiv xarita ochiladi:
┌───────────────────────────────────────────────────────────┐
│ node_modules │
│ ┌──────────────────┐ ┌───────────────┐ ┌───────────────┐ │
│ │ moment │ │ lodash │ │ chart.js │ │
│ │ 290 KB │ │ 72 KB │ │ 210 KB │ │
│ │ ┌──────────────┐ │ │ │ │ │ │
│ │ │ locale/ 210KB│ │ │ │ │ │ │
│ │ └──────────────┘ │ │ │ │ │ │
│ └──────────────────┘ └───────────────┘ └───────────────┘ │
│ ┌─────────┐ ┌───────┐ src/ (sizning kodingiz) │
│ │ react- │ │ react │ ┌──────────┐ │
│ │ dom │ │ │ │ 150 KB │ │
│ └─────────┘ └───────┘ └──────────┘ │
└───────────────────────────────────────────────────────────┘
To'rtburchak qanchalik katta bo'lsa — modul shunchalik og'ir. Birinchi qarashdayoq aybdorlar ko'rinadi.
Doimiy foydalanish uchun — rollup-plugin-visualizer ni Vite konfiguratsiyasiga plagin sifatida qo'shish mumkin; u har build da stats.html yaratadi.
Kutubxona hajmini oldindan tekshirish
O'rnatishdan oldin: bundlephobia.com yoki pkg-size.dev — paket nomini yozing, minified va gzip hajmini, tree shaking ni qo'llab-quvvatlashini ko'rasiz.
2-qadam: tree shaking
Tree shaking — bundler ishlatilmagan kodni chiqarib tashlaydi. Lekin faqat to'g'ri import qilinganda:
// ❌ butun kutubxona (CommonJS, tree shaking ishlamaydi)
import _ from 'lodash';
_.debounce(fn, 300);
// ✅ faqat bitta funksiya
import debounce from 'lodash/debounce';
// ✅ ES modul versiyasi — tree shaking ishlaydi
import { debounce } from 'lodash-es';
Tree shaking ishlashi uchun kutubxona ES modullar (import/export) da yozilgan bo'lishi kerak. Eski CommonJS (require) kutubxonalar to'liq kiradi.
Ikonkalar
// ❌ ba'zi kutubxonalarda — hamma ikonkalar
import * as Icons from 'lucide-react';
<Icons.Search />
// ✅ faqat kerakli
import { Search, ShoppingCart } from 'lucide-react';
[!WARNING]
import * as XvaObject.keys(Icons)kabi dinamik murojaat tree shaking ni o'chiradi: bundler qaysi qismlar ishlatilishini oldindan bilolmaydi va hammasini qo'shadi.
3-qadam: yengilroq muqobillar
| Og'ir | Hajm (gzip) | Yengil muqobil | Hajm (gzip) |
|---|---|---|---|
moment |
~70 KB | date-fns (faqat kerakli funksiyalar) yoki dayjs |
2–7 KB |
lodash (to'liq) |
~25 KB | lodash-es (tree shaking) yoki o'zingiz yozgan 3 qator |
1 KB |
axios |
~14 KB | O'rnatilgan fetch |
0 KB |
uuid |
~4 KB | crypto.randomUUID() |
0 KB |
classnames |
~0.5 KB | clsx |
~0.3 KB |
Ko'p kutubxonalar bugun brauzerning o'zida bor:
crypto.randomUUID(); // uuid
structuredClone(obyekt); // lodash.cloneDeep
new Intl.NumberFormat('uz-UZ').format(1234567); // raqam formatlash
new Intl.DateTimeFormat('uz', { dateStyle: 'long' }); // sana formatlash
new Intl.RelativeTimeFormat('uz').format(-3, 'day'); // "3 kun oldin"
array.at(-1); // oxirgi element
Object.groupBy(royxat, (x) => x.kategoriya); // lodash.groupBy
[!INFO] Hajm jadvaldagi raqamlar taxminiy va versiyaga qarab o'zgaradi — o'rnatishdan oldin bundlephobia da joriy hajmni tekshiring.
4-qadam: code splitting
69-darsdan: hamma narsa birinchi yuklanishda kerak emas.
// Sahifalar — lazy
const Admin = lazy(() => import('./pages/Admin'));
// Og'ir kutubxonalar — kerak bo'lganda
async function eksport() {
const { utils, writeFile } = await import('xlsx');
// ...
}
Asosiy maqsad — birinchi ekran uchun kerakli JavaScript ni minimal qilish. Qolgani — keyin, fonda yoki kerak bo'lganda.
5-qadam: vendor chunk lar va kesh
Vite avtomatik ravishda node_modules dagi umumiy kodni alohida chunk larga ajratadi va fayl nomlariga hash qo'shadi (index-8f3a2c.js). Bu keshlash uchun muhim:
- Siz o'z kodingizni o'zgartirdingiz → faqat sizning chunk ingiz hash i o'zgaradi
- React va boshqa kutubxonalar o'zgarmadi → foydalanuvchi brauzeri ularni keshdan oladi
Serverda hash li fayllar uchun uzoq muddatli kesh sozlang:
Cache-Control: public, max-age=31536000, immutable
index.html uchun esa — keshlamaslik (no-cache), aks holda foydalanuvchi yangi versiyani ko'rmaydi.
Siqish
Serverda gzip yoki brotli siqish yoqilganiga ishonch hosil qiling — JavaScript va CSS hajmini 3–5 baravar kamaytiradi. Vercel, Netlify (90-dars) va ko'p hosting lar buni avtomatik qiladi; o'z serveringizda (nginx) — sozlash kerak.
Tekshirish: DevTools → Network → JS fayl → Response Headers da content-encoding: br yoki gzip.
Byudjet
Hajm sekin-asta, sezilmasdan o'sadi: har oy bitta "kichkina" kutubxona. Buni to'xtatish uchun — performance budget:
Birinchi yuklash JavaScript: ≤ 170 KB (gzip)
Har bir route chunk: ≤ 50 KB (gzip)
size-limit kabi vositalar CI da (har bir Pull Request da) hajmni tekshiradi va chegaradan oshsa — xato beradi. Shunda "kim 300 KB qo'shdi?" degan savol code review paytida hal bo'ladi, production da emas.
Nima uchun shunday?
Nima uchun JavaScript hajmi rasmlar hajmidan ko'ra muhimroq hisoblanadi — 200 KB rasm va 200 KB JavaScript bir xil yuklanadi-ku?
Yuklanishi bir xil, lekin keyingi qadam boshqacha. 200 KB rasm yuklangandan keyin brauzer uni tezda dekodlab, ekranga chiqaradi — va bu jarayon asosiy oqimni (main thread) bloklamaydi. 200 KB JavaScript esa tahlil qilinishi, kompilyatsiya qilinishi va bajarilishi kerak — va bularning hammasi asosiy oqimda, ya'ni shu vaqtda sahifa tugma bosishga ham, scroll ga ham javob bermaydi. O'rtacha Android telefonda bu flagman kompyuterdan 5–10 baravar sekinroq. Shuning uchun JavaScript ning har bir kilobayti — eng qimmat kilobayt, va uni kamaytirish foydalanuvchi tajribasini yaxshilashning eng samarali usullaridan biri.
Xulosa
Eslab qoling:
- JavaScript — uch marta qimmat: yuklash, tahlil, bajarish; ayniqsa telefonlarda
- Avval tahlil:
npx vite-bundle-visualizer; o'rnatishdan oldin — bundlephobia - Tree shaking: nomlangan importlar, ES modul versiyalari (
lodash-es);import *dan qoching - Yengil muqobillar va brauzerning o'rnatilgan API lari (
fetch,Intl,crypto.randomUUID,structuredClone) - Code splitting — birinchi ekran uchun minimal JavaScript
- Hash li fayllar — uzoq kesh;
index.html— keshlamaslik - gzip/brotli siqish; performance budget va CI da tekshirish
Keyingi bo'lim
11-bo'lim: Testing — Vitest, React Testing Library va MSW.