React Profiler — sekin componentlarni topish
Muammodan boshlaylik
Foydalanuvchilar shikoyat qilyapti: "Filtr tugmasini bossam, sahifa bir soniya qotib qoladi". Siz kodga qaraysiz: 40 ta komponent, hammasi oddiyga o'xshaydi. Qaysi biri sekin?
Taxmin qilib boshlaysiz: bu yerga memo, u yerga useMemo, mana bu funksiyaga useCallback... Bir soatdan keyin kod murakkablashdi, sahifa esa hali ham sekin. Chunki muammo siz o'ylagan joyda emas edi.
Performance optimizatsiyasining birinchi qoidasi: avval o'lcha, keyin tuzat. React buning uchun maxsus vosita beradi — Profiler.
React DevTools o'rnatish
Brauzer kengaytmasi: React Developer Tools (Chrome, Firefox, Edge). O'rnatgandan keyin DevTools da ikki yangi tab paydo bo'ladi:
- ⚛ Components — komponentlar daraxti, props, state, hook lar
- ⚛ Profiler — render vaqtlarini yozib olish
Birinchi qadam: render larni ko'rish
Components tab → ⚙ sozlamalar → "Highlight updates when components render" ni yoqing.
Endi har bir render qilingan komponent ekranda rangli ramka bilan yonib o'chadi:
- Ko'k/yashil — kamdan-kam render
- Sariq/qizil — tez-tez render
Qidiruv maydoniga yozing. Agar har harfda butun sahifa yonib o'chsa — muammo topildi: keraksiz render lar (67–68-darslar).
Profiler bilan yozib olish
- Profiler tabini oching
- ⏺ (Record) tugmasini bosing
- Sekin amalni bajaring — filtr tugmasini bosing
- ⏹ (Stop) ni bosing
Commit lar
Yuqori o'ng burchakda — commit lar ustunlari. Har bir commit — React ning DOM ni bir marta yangilashi (67-dars). Ustun balandligi va rangi — shu commit qancha vaqt olgani:
▁ ▁ █ ▁ ▂ ▁
↑
sekin commit — 340 ms
Eng baland ustunni tanlang.
Flamegraph — olov grafigi
App (2.1ms of 340ms)
├── Header (0.3ms)
├── Filtrlar (1.2ms)
└── MahsulotRoyxati (336ms) ████████████████████████████
├── MahsulotKartochka (0.6ms)
├── MahsulotKartochka (0.7ms)
├── ... × 500
- Har bir chiziq — komponent; kengligi — u va bolalarining render vaqti
- Rang: sariq/qizil — sekin, ko'k/yashil — tez, kulrang — bu commit da render bo'lmagan
- "2.1ms of 340ms" — komponentning o'zi 2.1 ms, bolalari bilan birga 340 ms
Bu misolda aybdor aniq: MahsulotRoyxati — 500 ta kartochka.
Ranked — tartiblangan ro'yxat
Flamegraph yonidagi Ranked ko'rinish — komponentlarni o'z render vaqti bo'yicha tartiblaydi. Eng sekini tepada.
"Why did this render?"
Profiler sozlamalari (⚙) → "Record why each component rendered while profiling" ni yoqing. Endi komponentni tanlasangiz, o'ng panelda sababi ko'rinadi:
| Sabab | Ma'nosi | Mumkin bo'lgan yechim |
|---|---|---|
The parent component rendered |
Ota-ona render bo'ldi | State ni pastga tushirish, memo (67–68-darslar) |
Props changed: (onSelect) |
Prop o'zgardi | Har renderda yangi funksiya? → useCallback |
Props changed: (filtr) |
Har renderda yangi obyekt? → useMemo yoki konstanta |
|
Hook 2 changed |
2-hook (state) o'zgardi | Haqiqiy o'zgarish yoki keraksiz setState? |
Context changed |
Context qiymati o'zgardi | Context ni bo'lish, value ni memo qilish |
Bu ma'lumot taxmin qilishni butunlay to'xtatadi.
Profiler komponenti — koddan o'lchash
Ba'zan vaqtni dasturiy ravishda o'lchash kerak (masalan, analitikaga yuborish):
import { Profiler } from 'react';
function onRender(id, phase, actualDuration, baseDuration) {
if (actualDuration > 16) {
console.warn(`${id} (${phase}): ${actualDuration.toFixed(1)} ms`);
}
}
<Profiler id="MahsulotRoyxati" onRender={onRender}>
<MahsulotRoyxati />
</Profiler>
| Parametr | Ma'nosi |
|---|---|
id |
Profiler nomi |
phase |
'mount' (birinchi) yoki 'update' / 'nested-update' |
actualDuration |
Shu commit da render ga ketgan vaqt (memo bilan o'tkazib yuborilganlar hisobga olinmaydi) |
baseDuration |
Memo siz butun daraxtni render qilish uchun taxminiy vaqt |
actualDuration va baseDuration ni solishtirib, memoizatsiya qancha foyda berayotganini ko'rish mumkin.
[!INFO] Nega 16 ms? Ekran sekundiga 60 marta yangilanadi: 1000 / 60 ≈ 16.7 ms. Agar bitta yangilanish shundan ko'p vaqt olsa, brauzer kadrni o'tkazib yuboradi va foydalanuvchi "qotish" ni sezadi. 120 Hz ekranlarda chegara yanada qattiqroq — ~8 ms.
Muhim: development va production
Development rejimida React ancha sekinroq ishlaydi: qo'shimcha tekshiruvlar, ogohlantirishlar, Strict Mode da ikki marta render (84-dars). Development da 200 ms bo'lgan narsa production da 40 ms bo'lishi mumkin.
- Qaysi komponent sekinligini topish uchun — development da Profiler yetarli (nisbatlar to'g'ri)
- Haqiqiy raqamlar uchun — production build ni o'lchang:
npm run build
npm run preview
Chrome Performance tab
React Profiler faqat React render larini ko'rsatadi. Muammo boshqa joyda bo'lishi mumkin: og'ir JavaScript hisob-kitob, katta DOM, layout, rasm yuklanishi. Kengroq ko'rinish uchun — Chrome DevTools → Performance:
- ⚙ → CPU: 4× slowdown — o'rtacha telefonni taqlid qilish (sizning kompyuteringiz foydalanuvchilarnikidan ancha tez)
- Record → amal → Stop
- Main qatorida qizil uchburchakli uzun vazifalar (Long Tasks, 50 ms dan ortiq) — asosiy muammolar
Shuningdek Lighthouse tab — sahifa yuklanishi metrikalari (LCP, INP, CLS).
Optimizatsiya jarayoni
1. Muammoni qayta hosil qil → aniq amal: "filtr bosilganda"
2. O'lcha → Profiler, CPU 4× slowdown
3. Aybdorni top → Flamegraph, Ranked, "Why did this render?"
4. Bitta o'zgarish kirit → state ni pastga, memo, virtualizatsiya...
5. Qayta o'lcha → yaxshilandimi? yo'q bo'lsa — qaytar
[!TIP] Bir vaqtda faqat bitta o'zgarish kiriting va har biridan keyin o'lchang. Aks holda qaysi o'zgarish yordam berganini bilmaysiz — va keraksiz murakkablikni kodda qoldirasiz. Yordam bermagan optimizatsiyani olib tashlang.
Nima uchun shunday?
Nima uchun tajribali dasturchilar ham sekin joyni taxmin qila olmaydi?
Chunki zamonaviy kompyuterlar va brauzerlar intuitsiyaga zid ishlaydi. 1000 ta elementli massivni filter qilish — bir necha mikrosoniya, ya'ni deyarli bepul. Shu bilan birga bitta noto'g'ri joylashgan setState butun daraxtni har harfda render qilishi, yoki katta rasm layout ni qayta hisoblashga majburlashi mumkin. Odamlar "murakkab ko'ringan" kodni sekin deb o'ylaydi, lekin sekinlik ko'pincha oddiy ko'ringan joyda bo'ladi. Donald Knut ning mashhur iborasi bor: "Muddatidan oldingi optimizatsiya — barcha yovuzliklarning ildizi". Profiler bu tamoyilni amalga oshiradi: siz faqat haqiqatan sekin joyni, isbotlangan holda tuzatasiz.
Xulosa
Eslab qoling:
- Avval o'lcha, keyin tuzat — taxmin qilma
- React DevTools: Highlight updates — keraksiz render larni ko'rish
- Profiler: Record → amal → Stop; commit lar, Flamegraph, Ranked
- "Why did this render?" — ota-ona, props, hook, Context
<Profiler id onRender>— koddan o'lchash; 16 ms — bitta kadr chegarasi- Development sekinroq; haqiqiy raqamlar — production build da
- Chrome Performance (CPU 4× slowdown) va Lighthouse — kengroq tahlil
- Bitta o'zgarish → qayta o'lchash; yordam bermaganini olib tashlash
Keyingi dars
72-dars: Bundle Size — tahlil qilish, optimizatsiya