Seriya: JavaScript Basics Dars 91

Performance Budget

Performance budget nima, miqdoriy va vaqt asosidagi budget turlari, Core Web Vitals (LCP, INP, CLS), Long Task va Event Loop bilan bog'liqligi, Webpack/Lighthouse CI orqali avtomatik nazorat, va bundle hajmining V8 Parse/Compile bosqichlariga qanday ta'sir qilishi.

91-dars

Performance Budget

Performance budget — bu loyihaga oldindan belgilangan, qat'iy raqamli chegaralar qo'yish: "bizning sahifamiz hech qachon 200KB JS'dan oshmasin", "hech qachon 3 soniyadan sekin yuklanmasin". Bu — texnologiya emas, balki muhandislik intizomi: performance'ni "keyin optimallashtiramiz" deb qoldirish o'rniga, har bir commit'da avtomatik tekshiriladigan chegara sifatida kiritish.


1. Qaysi metrikalar bo'yicha budget qo'yiladi

Bu yerda ikki xil budget turi bor — ularni ajratish muhim:

Turi Nima o'lchaydi Misol
Miqdoriy (Quantity-based) Fayl hajmi, so'rovlar soni "JS bundle ≤ 170KB (gzip)"
Vaqt asosidagi (Timing-based) Foydalanuvchi his qiladigan tezlik "LCP ≤ 2.5 soniya"

Miqdoriy budget'ni nazorat qilish oson (build vaqtida hisoblab bo'ladi), lekin haqiqiy tajribani to'liq aks ettirmaydi — 170KB JS sekin telefonda sekin, kuchli laptop'da tez ishlashi mumkin. Shuning uchun ikkalasi birga ishlatiladi.


2. Core Web Vitals — Google'ning rasmiy vaqt metrikalari

Bu uchtasi — hozirgi zamon veb-performance standarti, hattoki qidiruv reytingiga ham ta'sir qiladi:

Metrika Nima o'lchaydi Yaxshi chegarasi
LCP (Largest Contentful Paint) Eng katta ko'rinadigan element qachon chizilgani (odatda hero rasm/sarlavha) ≤ 2.5s
INP (Interaction to Next Paint) Foydalanuvchi bosgandan, ekranda javob ko'rinishigacha bo'lgan kechikish ≤ 200ms
CLS (Cumulative Layout Shift) Sahifa yuklanish paytida elementlar qanchalik "sakraydi" (masalan, rasm keyin yuklanib, matnni pastga surib yuborishi) ≤ 0.1

LCP nima uchun muhim — V8 va rendering pipeline bilan bog'liqligi

1. HTML kelmoqda → Parser boshlaydi
2. CSS/JS kerakli fayllar so'raladi
3. V8 — asosiy JS bundle'ni PARSE + COMPILE + EXECUTE qiladi
4. Shu paytda — Main Thread band, render bloklanadi
5. JS tugagach — DOM to'liq quriladi
6. Layout + Paint — ekranga chiqadi

Agar sizning JS bundle'ingiz katta bo'lsa (masalan, 1MB), 3-qadam uzoq davom etadi — bu bevosita LCPni yomonlashtiradi, chunki brauzer render qilishdan oldin JS'ni tugatishi kerak bo'lgan holatlar ko'p uchraydi (masalan, React kabi framework'larda, sahifa JS orqali quriladigan bo'lsa).

INP — nega V8'ning Long Task tushunchasi bilan bog'liq

button.addEventListener('click', () => {
  // agar bu funksiya 300ms davom etsa
  processHugeArray(data); // Main Thread BAND, foydalanuvchi hech narsa qila olmaydi
});

Brauzer 50msdan uzoq davom etadigan har qanday sinxron JS ishini "Long Task" deb belgilaydi. Agar Long Task davomida foydalanuvchi biror joyni bossa — event darhol ishlanmaydi, u navbatga tushib qoladi (Event Loop mexanizmi — call stack band bo'lsa, hech narsa ishlay olmaydi). INP aynan shu kechikishni o'lchaydi.


3. Miqdoriy budget — real konfiguratsiya

Zamonaviy build tool'larda (Webpack, Vite) budget avtomatik tekshiriladi:

// webpack.config.js
module.exports = {
  performance: {
    maxAssetSize: 250000,      // bitta fayl 250KB'dan oshmasin
    maxEntrypointSize: 400000, // umumiy entry bundle 400KB'dan oshmasin
    hints: 'error'             // oshsa — BUILD TO'XTAYDI, ogohlantirish emas
  }
}

hints: 'error' — bu muhim qaror: ko'p jamoalar buni faqat warning qilib qo'yadi, natijada hech kim e'tibor bermaydi. 'error' qilib qo'yilsa — CI pipeline build'ni bloklaydi, dasturchi budget'ni oshirib yuborgan kodni merge qilolmaydi, to budgetga qaytarmaguncha yoki ataylab oshirilishini asoslab bermaguncha.


4. Nega "200KB JS" degan raqamning o'zi ham yetarli emas — Parse/Compile narxi

Bu yerda chuqur V8 darajasidagi tushuncha bor: JS faylining hajmi (KB) va uni V8 qayta ishlash vaqti — chiziqli bog'liq emas.

100KB JSON data  →  V8 buni FAQAT parse qiladi (tez, oddiy)
100KB JS kod     →  V8 buni PARSE + COMPILE qiladi (sekinroq)

Bundan tashqari, qurilma quvvati katta rol o'ynaydi:

Qurilma 100KB JS'ni Parse+Compile qilish vaqti (taxminiy)
Zamonaviy flagman telefon ~30-50ms
O'rta narxli Android (masalan, 2020-yilgi) ~150-300ms
Arzon, past quvvatli qurilma ~500ms+

Shuning uchun Google va boshqa mutaxassislar tavsiya qilgan real qoida — "o'rtacha qurilmada test qiling", kuchli laptop/flagman telefonda emas — chunki aynan siz o'rgangan JIT compilation narxi (Ignition → interpretatsiya, keyin Sparkplug/TurboFan → optimallashtirish) past quvvatli protsessorlarda eksponensial darajada sekinlashadi.


5. Nima uchun bu KB'dan ko'ra ko'proq narsaga bog'liq — "byte uchun narx" jadvali

Turli resurs turlari uchun brauzer xarajati boshqacha:

Resurs turi Brauzer nima qiladi Nisbiy "og'irlik"
Rasm (JPEG/PNG) Faqat dekodlash, GPU'ga yuklash Past
CSS Parse + CSSOM qurish, render bloklaydi O'rta
JS Parse + Compile + Execute (V8, single-thread!) Eng yuqori
Font Yuklanguncha matn "yashirin" bo'lishi mumkin (FOIT) O'rta

Shuning uchun performance mutaxassislari orasida mashhur qoida bor: "1KB JS — 1KB rasmdan qimmatroq" — chunki rasm faqat dekodlanadi (ko'pincha GPU/alohida thread'da), JS esa majburiy ravishda main thread'da, ketma-ket qayta ishlanadi.


6. Budget'ni avtomatik nazorat qilish — Lighthouse CI

// lighthouserc.json
{
  "ci": {
    "assert": {
      "assertions": {
        "largest-contentful-paint": ["error", { "maxNumericValue": 2500 }],
        "cumulative-layout-shift": ["error", { "maxNumericValue": 0.1 }],
        "total-byte-weight": ["error", { "maxNumericValue": 500000 }]
      }
    }
  }
}

Bu konfiguratsiya har bir Pull Request'da avtomatik ishlaydi: Lighthouse sahifani sinov qiladi, agar LCP 2.5 soniyadan oshsa — CI qizil bo'ladi, PR merge qilinmaydi. Bu — budget'ni "hujjat"dan (hech kim o'qimaydigan wiki sahifasi) "kod"ga (majburiy, tekshiriladigan) aylantiradi.


7. Budget'ni "buzuvchi" odatiy sabablar — amaliy nazorat ro'yxati

Muammo Yechim
Katta kutubxona butun holda import qilingan (import _ from 'lodash') Faqat kerakli funksiyani import qilish (Tree shakingni eslang)
Rasm optimallashtirilmagan (5MB PNG) WebP/AVIF formatga o'tish, srcset bilan moslashtirish
Barcha JS bitta bundle'da Code splitting — faqat kerakli sahifa uchun kod yuklash
Fontlar bloklovchi font-display: swap, faqat kerakli weight'larni yuklash
Uchinchi tomon skriptlari (analytics, reklama) async/defer, yoki Web Workerga (Partytown kabi vositalar bilan) chiqarish

Diqqat qiling — bu yerda avval o'rgangan hamma narsa (Tree shaking, Code splitting, Web Worker) aynan shu budget'ni ushlab turish uchun ishlatiladigan amaliy vositalar ekan.


8. V8 darajasida — qisqa, yakuniy bog'lanish

Performance budget — bu o'zi V8'da amalga oshirilmagan tushuncha (bu — muhandislik jarayoni, API emas), lekin uning barcha raqamlari to'g'ridan-to'g'ri V8'ning ichki bosqichlariga bog'liq:

Bundle hajmi (KB)
    ↓ ta'sir qiladi
Parse vaqti (Ignition — bytecode'ga aylantirish)
    ↓ ta'sir qiladi
Execute vaqti (birinchi marta — interpretatsiya, keyin JIT optimallashtirish)
    ↓ ta'sir qiladi
Main Thread bandligi
    ↓ ta'sir qiladi
LCP / INP (foydalanuvchi HIS QILADIGAN tezlik)

Ya'ni performance budget — bu (Memory & Performance, V8 JIT) va (Modular Thinking, Tree shaking/Code splitting) o'rganilgan texnik bilimlarni, biznes/foydalanuvchi natijasiga (raqamli, o'lchanadigan chegaralarga) bog'lovchi yakuniy qatlam.