Mundarija (32)
- Bu darsda
- 1. Nega bu kerak?
- 2. Performance paneli
- 2.1 Profil yozish
- 2.2 Vaqt chizig'ini o'qish
- 2.3 Flame chart: "olov" diagrammasi
- 2.4 Pastki jadvallar: Summary, Bottom-Up, Call tree
- 2.5 Amaliyot: sekin menyuni profil bilan topamiz
- 3. Memory paneli
- 3.1 Uch profil turi
- 3.2 Xotira "tishlari"
- 4. Network paneli: waterfall'ni o'qish
- 4.1 Tanish ustunlar, yangi savollar
- 4.2 Initiator va Priority
- 4.3 Uch foydali imkoniyat
- 5. Lighthouse: ball qanday hisoblanadi
- 5.1 Beshta o'lchov, beshta og'irlik
- 5.2 Buyruq qatoridan
- 6. Ko'p uchraydigan xatolar
- 6.1 Sekinlashtirmasdan profil yozish
- 6.2 Total time bo'yicha qidirish
- 6.3 Kengaytmali oynada o'lchash
- 6.4 Bir vaqtda ko'p o'zgarish
- 6.5 HAR faylni tekshirmasdan ulashish
- 7. Mashqlar
- 1-mashq (oson): Formatlovchini tashqariga chiqaring
- 2-mashq (o'rta): Siljish aybdorini toping
- 3-mashq (qiyin): Network'da sekin internetni sinang
- 4-mashq: Vazifalar qadami — CLS'ni topib tuzatish
- 8. Real ishda
- Xulosa
- Manbalar
DevTools Performance, Memory va Network: sekinlik sababini profil bilan topish
Qisqacha: Sekinlikni taxmin bilan emas, profil bilan qidiring. Performance paneli sahifada nima bo'lganini vaqt chizig'iga yozadi: flame chart'da qaysi funksiya qancha vaqt olgani, uzun task'lar, siljishlar va bosishlar. Memory — xotira qayerda o'sayotganini, Network — fayllar qachon va qanday tartibda kelganini ko'rsatadi. Tartib doim bir xil: o'lcha → sababni top → tuzat → yana o'lcha. Lighthouse esa natijani bitta ball bilan tekshiradi.
Bu darsda
- Performance panelida profil yozib, flame chart va Bottom-Up jadvalidan eng sekin funksiyani topa olasiz.
- Uzun task, layout siljishi va sekin bosishni vaqt chizig'ida taniysiz.
- Memory panelining uch profil turini va Performance monitor'ni qachon ishlatishni bilasiz.
- Network waterfall'ini o'qib, so'rovlar tartibi, tashabbuskori va ustuvorligini tushuntira olasiz.
- Lighthouse balli qanday hisoblanishini bilasiz va
vazifalardagi CLS'ni topib tuzatasiz.
Oldin bilishingiz kerak: Asosiy thread'ni bo'shatish, Performance API va Core Web Vitals, Chrome DevTools II: Network, Application va Lighthouse, Xotira sizishlari va ularni topish.
1. Nega bu kerak?
Oldingi darsda vazifalar o'z Core Web Vitals'ini yozdi: CLS — 0,139, "yaxshilash kerak". Nimadir sakrayapti. Lekin nima?
Sardor taxmin qildi: "Shrift kech yuklanyapti". U CSS'ni yarim soat o'zgartirdi — CLS joyida qoldi. Keyin "rasm" deb o'yladi — vazifalar da rasm umuman yo'q. Taxmin bilan tuzatish — ko'zni yumib nishonga otish.
Shifokor ham operatsiyadan oldin rentgen qiladi. Dasturchining rentgeni — DevTools'dagi profil. U "nimadir sekin" degan hisni aniq javobga aylantiradi: qaysi element, qaysi funksiya, qachon. Ish tartibi doim bir xil:
flowchart LR
A["O'lcha<br/>(Lighthouse,<br/>Web Vitals)"] --> B["Profil yoz<br/>(Performance)"]
B --> C["Sababni top<br/>(flame chart,<br/>Insights)"]
C --> D["Tuzat<br/>(bitta o'zgarish)"]
D --> E["Yana o'lcha"]
E -->|"yaxshilanmadi"| BMuhim qoida: bir vaqtda bitta o'zgarish. Uchta narsani birdan o'zgartirsangiz, qaysi biri yordam berganini bilmaysiz.
2. Performance paneli
2.1 Profil yozish
Chrome DevTools II darsida Network va Lighthouse'ni ko'rgan edik. Performance paneli — ularning "katta akasi": sahifaning har millisekundini yozadi.
Ikki yo'l bor:
- Record (
Ctrl + E) — yozishni boshlaysiz, sahifada biror ish qilasiz (tugma bosish, aylantirish), to'xtatasiz. Bosish va animatsiyani tekshirish uchun. - Record and reload (
Ctrl + Shift + E) — sahifani qayta yuklab, yuklanishni yozadi. LCP va CLS uchun.
Yozishdan oldin uch sozlama:
- CPU throttling — protsessorni 4× yoki 6× sekinlashtirish. Kompyuteringiz telefondan ancha tez; sekinlashtirmasangiz, muammoni ko'rmay qolasiz.
- Network — sekin tarmoq (masalan, "Slow 4G").
- Inkognito oyna — kengaytmalar profilga o'z skriptlarini qo'shmasin.
Panel ochilganda avval Live metrics ko'rinishi chiqadi: shu sahifadagi LCP, CLS va INP jonli yangilanib turadi. Har bosish pastdagi ro'yxatga yoziladi. Performance API va Core Web Vitals darsidagi o'lchovlar — shu yerda, kod yozmasdan.
2.2 Vaqt chizig'ini o'qish
Profil yozilgach, ekranda bir nechta "qator" (track) paydo bo'ladi. Eng muhimlari:
| Qator | Nima ko'rsatadi |
|---|---|
| Network | So'rovlar vaqt bo'yicha |
| Frames | Kadrlar; tushib qolgan kadr — rangli |
| Main | Asosiy thread: task'lar va flame chart |
| Timings | performance.mark / measure, LCP, FCP belgilari |
| Layout shifts | Siljishlar — binafsha romblar |
| Interactions | Bosishlar va ularning vaqti |
Timings qatori — tanish narsa. Performance API darsidagi «Menyu yuklanishini o'lchang» mashqining menu-fetch o'lchovi aynan shu yerda nomi bilan chiqadi. O'z kodingizdagi muhim bosqichlarga mark qo'ysangiz, profil o'qish ancha osonlashadi.
2.3 Flame chart: "olov" diagrammasi
Main qatorini kattalashtirsangiz, rangli to'rtburchaklar "minorasi"ni ko'rasiz. Bu flame chart (olov diagrammasi):
- Gorizontal — vaqt. To'rtburchak qancha keng bo'lsa, shuncha uzoq ishlagan.
- Vertikal — chaqiruvlar zanjiri (call stack). Tepada — task (masalan,
clickhodisasi), uning ostida chaqirilgan funksiya, uning ostida u chaqirgan funksiya. - Rang — ish turi: sariq — JavaScript (Scripting), binafsha — style va layout (Rendering), yashil — bo'yash (Painting).
- Qizil burchak — task'ning yuqori o'ng burchagidagi qizil uchburchak: bu uzun task (50 ms dan ko'p). Uning 50 ms dan oshgan qismi qizil chiziqlar bilan bo'yaladi.
Qanday o'qiladi? Avval keng to'rtburchakni toping. Keyin uning ostiga tushing: qaysi bolasi eng keng? Shu tarzda pastga — "eng keng eng past" funksiyaga. Sekinlik o'sha yerda.
Aylantirish "qotsa", flame chart'da wheel yoki touchmove tinglovchisini qidiring: brauzer aylantirishdan oldin uning tugashini kutadi. Tinglovchi preventDefault chaqirmasa, unga passive: true bering (Listener opsiyalari) — kutish yo'qoladi.
Siz JS dvigateli ichida darsida ko'rgan kompilyatsiya bosqichlari ham shu yerda — "Compile" so'zi bilan boshlanadigan bloklar. Majburiy layout esa (Rendering pipeline va layout thrashing) binafsha "Layout" bloki va ustida Forced reflow ogohlantirishi bilan chiqadi.
2.4 Pastki jadvallar: Summary, Bottom-Up, Call tree
Flame chart'da bir qismni belgilasangiz, pastda jadvallar paydo bo'ladi:
- Summary — doira diagramma: vaqtning qancha qismi Scripting, Rendering, Painting, Idle'ga ketgani.
- Bottom-Up — funksiyalar ro'yxati, o'z vaqti (self time) bo'yicha saralangan. O'z vaqti — funksiyaning ichida, boshqa funksiyalarni chaqirmasdan o'tkazgan vaqti. "Vaqtni aynan kim yeyapti?" savoliga eng tez javob.
- Call tree — yuqoridan pastga daraxt: qaysi task qaysi funksiyalarni chaqirgan.
- Event log — hamma voqealar vaqt tartibida.
O'ng tomonda Insights bo'limi ham bor. U profilni o'zi tahlil qilib, tayyor xulosalar beradi: "LCP breakdown" (LCP qaysi bosqichda kechikdi), "Layout shift culprits" (siljishning aybdori), "INP breakdown" (kutish, ishlov, chizish), "Render-blocking requests". Bu Lighthouse'dagi Insights bilan bir xil manba.
2.5 Amaliyot: sekin menyuni profil bilan topamiz
«Bahor» saytida 2 000 ta taomli menyu bor. «Menyuni chiz» bosilganda sahifa biroz qotadi. Quyidagi oynani oching, keyin DevTools'da Record ni bosing, tugmani 2–3 marta bosing va to'xtating:
<style>
body { font: 1rem/1.5 system-ui, sans-serif; margin: 1rem; }
button { font: inherit; padding: 0.4rem 0.8rem; }
#menu { max-height: 12rem; overflow: auto; }
</style>
<button id="render" type="button">Menyuni chiz</button>
<p>Oxirgi chizish: <output id="time">—</output></p>
<ul id="menu"></ul>
<script>
const names = ["Osh", "Manti", "Lag'mon", "Somsa", "Shashlik"];
const items = Array.from({ length: 2000 }, (_, i) => ({
name: `${names[i % names.length]} ${i + 1}`,
price: 20000 + (i % 30) * 1000,
}));
function formatPrice(price) {
const formatter = new Intl.NumberFormat("uz", {
style: "currency", currency: "UZS", maximumFractionDigits: 0,
});
return formatter.format(price);
}
function createItem(item) {
const li = document.createElement("li");
li.textContent = `${item.name} — ${formatPrice(item.price)}`;
return li;
}
function renderMenu() {
const start = performance.now();
const list = document.getElementById("menu");
list.replaceChildren(...items.map(createItem));
const ms = performance.now() - start;
const out = document.getElementById("time");
out.textContent = `${Math.round(ms)} ms`;
}
document.getElementById("render").addEventListener("click",
renderMenu);
</script>Profilda nima ko'rinadi? Main qatorida har bosish — bitta click task'i. Uning ostida renderMenu, ostida map va createItem, eng pastda formatPrice — ko'p ingichka bo'laklar bo'lib.
Bottom-Up jadvalini oching va Self time bo'yicha saralang. Biz xuddi shu kodni Chrome 154 ning profilerida o'lchadik — DevTools'ning o'zi ishlatadigan profiler, faqat avtomatik ishga tushirilgan. JavaScript funksiyalari ichida birinchi o'rinda formatPrice — butun yozuv vaqtining taxminan 38 foizi. createItem, renderMenu va DOM'ga qo'shish (replaceChildren) — atigi bir necha foiz.
Sabab — Intl.NumberFormat darsidagi tanish tuzoq: formatlovchi har bir narx uchun qaytadan yaratilyapti. Yaratish — og'ir ish (til ma'lumotlarini qidirish), format esa tez. Tuzatish — formatlovchini funksiyadan tashqariga chiqarish, bir marta yaratish. Buni «Formatlovchini tashqariga chiqaring» mashqida qilasiz. Natija (6 ta bosish, mediana):
- Oldinhar narxga yangi formatlovchi43 ms
- Keyinbitta formatlovchi7 ms
- Oldin, CPU 4×telefonga yaqin207 ms
- Keyin, CPU 4×22 ms
Manba: O'lchov: Chrome 154 headless, Intel i5-12500H, Live Server kabi lokal sahifa, har holat 6 ta bosish, mediana; CPU 4× — CDP Emulation.setCPUThrottlingRate, 2026-10-05
Kompyuterda 43 ms — sezilmaydi ham. 4 baravar sekinlashtirilgan protsessorda esa 207 ms: bu uzun task va "yaxshilash kerak" INP. Mana nima uchun CPU throttling'siz profil yozmaslik kerak. Bitta qator o'zgarishi sakkiz-to'qqiz baravar tezlashtirdi — va biz qaysi qatorni o'zgartirishni taxmin qilmadik, profildan bildik.
Tekshirib ko'ring: Bottom-Up'da
renderMenuning Total time i eng katta, lekin Self time i juda kichik. Bu nimani anglatadi?
Javob
renderMenu ning o'zi deyarli ish qilmaydi — vaqtni u chaqirgan funksiyalar (createItem, formatPrice) sarflaydi. Total time — funksiya va uning ichidagi hamma chaqiruvlar, Self time — faqat funksiyaning o'z kodi. Sekin joyni topish uchun Self time bo'yicha saralanadi, keyin Call tree'da kim chaqirganini qidiriladi.
3. Memory paneli
Xotira sizishlari darsida heap snapshot, Comparison va Retainers bilan detached DOM'ni topgan edik. Bu yerda panelning qolgan imkoniyatlari.
3.1 Uch profil turi
| Tur | Qachon |
|---|---|
| Heap snapshot | Bir lahzadagi to'liq "surat": kim qancha joy egallagan, kim ushlab turibdi |
| Allocations on timeline | Vaqt bo'yicha: qachon nima yaratildi va qaysilari hali tirik |
| Allocation sampling | Qaysi funksiya ko'p xotira ajratyapti — kam yuk bilan, uzoq vaqt yozish mumkin |
Allocations on timeline sizish qidirishda juda qulay. Yozish paytida ko'k ustunlar paydo bo'ladi — yangi obyektlar. Ularning bir qismi keyin kulrangga aylanadi — GC ularni tozaladi (Xotira boshqaruvi va GC). Oxirigacha ko'k qolgan ustunlar — hali tirik obyektlar. Har bosishdan keyin bitta ko'k ustun qolib ketsa — shu bosish nimanidir "unutyapti".
3.2 Xotira "tishlari"
Ikki yordamchi vosita xotirani vaqt bo'yicha ko'rsatadi:
- Performance panelida Memory belgisini yoqib yozsangiz, flame chart ostida JS heap, DOM tugunlari (Nodes) va tinglovchilar soni chiziq bo'lib chiqadi.
- Performance monitor (
Ctrl + Shift + P→ "Show Performance monitor") — jonli grafik: CPU, JS heap, DOM tugunlari, tinglovchilar, soniyasiga layout'lar soni. U hech narsa yozmaydi, faqat "hozir" ni ko'rsatadi.
Sog'lom sahifada JS heap chizig'i "arra tishlari"ga o'xshaydi: o'sadi, GC ishlaydi, yana pastga tushadi. Tishlar pastki nuqtasi har safar ko'tarilib borsa — sizish. DOM tugunlari soni har bosishda o'sib, hech qachon kamaymasa — detached DOM yoki unutilgan elementlar.
Maslahat: Memory paneli bilan o'lchashdan oldin Collect garbage (axlat qutisi belgisi) tugmasini bosing. Aks holda GC hali ishlamagan "axlat" ham hisobga kiradi va siz sizish bo'lmagan joyda sizish ko'rasiz.
Tekshirib ko'ring: Performance monitor'da «Bahor» admin panelining DOM tugunlari soni har «Yangilash» bosilganda 1 200 → 2 400 → 3 600 bo'lib o'syapti va hech qachon kamaymayapti. Bu nimani anglatadi va keyingi qadam qaysi vosita?
Javob
Eski ro'yxat o'chirilmayapti yoki DOM'dan olinsa ham biror o'zgaruvchi uni ushlab turibdi — bu xotira sizishi. Sog'lom sahifada tugunlar soni har yangilashda taxminan bir xil qoladi. Keyingi qadam — Memory panelida ikki heap snapshot (bosishdan oldin va keyin), Comparison va Retainers: kim eski elementlarni ushlab turganini ko'rsatadi (Xotira sizishlari darsidagi usul).
4. Network paneli: waterfall'ni o'qish
4.1 Tanish ustunlar, yangi savollar
Chrome DevTools II darsida Network'ning ustunlari, filtrlari va Timing yorlig'ini ko'rgan edik. Endi JavaScript ilova nigohida uchta savol beramiz: qachon yuklandi, kim so'radi, qanchalik muhim.
Lighthouse vazifalar ni o'lchaganda (Web Vitals qadamidan keyingi holat) uning hisobotiga hamma so'rovlar yozildi — 24 ta, jami 35 KiB. Ulardan bir nechtasi (sahifa ochilganidan beri, ms):
| Fayl | Turi | Boshlandi | Tugadi |
|---|---|---|---|
/ (index.html) |
Document | 1 | 7 |
vazifalar.css |
Stylesheet | 71 | 74 |
holat.js … fayl.js (12 ta) |
Script | 71–76 | 78–87 |
asosiy.js |
Script | 76 | 87 |
olchov.js |
Script | 116 | 119 |
| API (Preflight + Fetch) | Fetch | 179 | 194 |
Waterfall'dagi manzara shu jadvalning o'zi:
- Modullar parallel. 12 ta modul 71–76 ms da birga boshlandi. Bu
index.htmldagi<link rel="modulepreload">ning xizmati (Dinamikimport()darsidagi g'oya). Busiz brauzerasosiy.jsni o'qib, keyin uning importlarini, keyin ularning importlarini — "zinapoya" bo'lib yuklardi. olchov.jskeyinroq. U 116 ms da —asosiy.jsishlagandan keyin, dinamikimport()bilan. Biz buni ataylab qildik.- Preflight. API so'rovidan oldin
OPTIONSqatori — CORS mijoz tomondan darsidagi preflight. Network'da u alohida qator bo'lib ko'rinadi.
4.2 Initiator va Priority
Ustun sarlavhasiga o'ng tugma bosib, yana ikki ustunni yoqing:
- Initiator — so'rovni kim boshlagan: HTML parser, skript (qaysi faylning qaysi qatori),
fetch. Ustiga sichqonchani olib borsangiz, chaqiruvlar zanjiri chiqadi. "Bu 2 MB lik rasmni kim so'rayapti?" degan savolga javob. - Priority — brauzer so'rovga bergan ustuvorlik: Highest, High, Medium, Low. Yuqoridagi hisobotda HTML va CSS — eng yuqori, skriptlar — High, manifest — Medium. Bosh rasm Low bo'lsa, LCP kechikadi —
fetchpriority="high"shuning uchun (Resurs maslahatlari).
4.3 Uch foydali imkoniyat
- Request blocking. So'rovga o'ng tugma → "Block request URL". Sahifa shu faylsiz ochiladi. "Reklama skripti tushib qolsa, saytimiz ishlaydimi?", "API ishlamasa nima ko'rinadi?" — bunday savollarni tekshirishning eng tez yo'li.
- Offline va throttling — tarmoq ro'yxatida. Kesh strategiyalari va offline darsidagi oflayn rejimni shu bilan sinadik.
- HAR eksport — barcha so'rovlarni
.harfaylga saqlash. Backend dasturchiga "menda shunday bo'ldi" deb yuborish uchun.
Diqqat: HAR fayl ichida cookie'lar,
Authorizationsarlavhalari va tokenlar bo'lishi mumkin. Chrome eksportda sezgir ma'lumotni olib tashlash imkonini beradi, lekin ochiq chatga yoki GitHub issue'ga yuborishdan oldin faylni tekshiring. Bu — haqiqiy sizib chiqish yo'li.
Tekshirib ko'ring: Waterfall'da «Bahor» bosh sahifasining katta rasmi eng oxirida, Priority ustunida Low bilan yuklanyapti. LCP esa 3,8 s. Qaysi ustun "rasmni kim so'radi?" deb javob beradi va qanday tuzatasiz?
Javob
Initiator ustuni: rasm HTML'dan emas, masalan, CSS yoki skriptdan so'ralgan bo'lsa, brauzer uni kech topadi. Tuzatish — rasmga fetchpriority="high" berish yoki uni preload bilan oldindan e'lon qilish (Resurs maslahatlari). Bosh rasmda loading="lazy" bo'lsa — olib tashlang. Keyin yana o'lchang: LCP kamaydimi?
5. Lighthouse: ball qanday hisoblanadi
5.1 Beshta o'lchov, beshta og'irlik
Lighthouse'ning Performance balli — beshta laboratoriya o'lchovidan yig'ilgan son. Har birining og'irligi bor. Lighthouse 13.5.0 hisobot faylidan olingan og'irliklar:
- TBTyuklanishdagi uzun task'lar30 %
- LCP25 %
- CLS25 %
- FCP10 %
- Speed Indexekran qanchalik tez to'ldi10 %
Manba: Lighthouse 13.5.0 hisoboti (vazifalar, holatlar/30): categories.performance.auditRefs weight, 2026-10-05
Uchta tanish o'lchov — LCP, CLS va FCP. TBT ni Performance API va Core Web Vitals darsida ko'rgan edik: yuklanishdagi uzun task'larning 50 ms dan oshgan qismlari yig'indisi. Yangisi — Speed Index: yuklanish paytida ekran qanchalik tez to'lib borgani. Lighthouse sahifa ochilishini kadrma-kadr suratga oladi va ko'rinadigan qism qanchalik tez "tayyor" bo'lganini hisoblaydi.
Nimaga qarang: CLS — ballning chorak qismi. Ya'ni bitta "sakrash" boshqa hamma narsa a'lo bo'lsa ham 90+ ni yo'qotishi mumkin. TBT (eng og'iri) — INP'ning laboratoriyadagi o'rinbosari (Performance API darsidagi "Laboratoriya va maydon").
5.2 Buyruq qatoridan
DevTools ichidagi Lighthouse qulay, lekin har safar bosish kerak. U npm paketi sifatida ham bor:
npx lighthouse@13.5.0 http://127.0.0.1:5500/ --viewnpx paketni vaqtincha yuklab ishga tushiradi, --view — hisobotni brauzerda ochadi. Versiyani aniq yozdik (@13.5.0): Lighthouse yangilanganda og'irliklar va o'lchovlar o'zgaradi, natijalarni taqqoslash uchun versiya bir xil bo'lishi kerak. Kurs uchun o'lchovlar xuddi shu versiya bilan, mobil rejimda olingan.
Bir narsani unutmang: Lighthouse simulyatsiya qiladi va har ishga tushirishda natija biroz farq qiladi. vazifalar da Performance balli ±1–2 ballga, LCP esa ±0,6 soniyagacha o'zgardi. Bitta o'lchovga emas, 3–5 ta o'lchovga qarang.
6. Ko'p uchraydigan xatolar
6.1 Sekinlashtirmasdan profil yozish
Kuchli kompyuterda 43 ms lik muammo ko'rinmaydi. Tuzatish: CPU 4× yoki 6×, tarmoq — sekin.
6.2 Total time bo'yicha qidirish
Eng katta Total time — deyarli doim tepadagi task yoki renderMenu kabi "boshliq" funksiya. Tuzatish: Bottom-Up'da Self time bo'yicha saralang.
6.3 Kengaytmali oynada o'lchash
Reklama to'suvchi, tarjimon kengaytmalar profilga o'z skriptlarini qo'shadi. Tuzatish: inkognito oyna yoki alohida Chrome profili.
6.4 Bir vaqtda ko'p o'zgarish
"Rasmlarni siqdim, shriftni o'zgartirdim, skriptni ko'chirdim — ball 8 ga oshdi." Qaysi biri yordam berdi? Bilmaysiz. Tuzatish: bitta o'zgarish — bitta o'lchov (kanondagi har qadam bitta xususiyat bo'lgani kabi).
6.5 HAR faylni tekshirmasdan ulashish
Token va cookie ochiq qolib ketadi. Tuzatish: sezgir ma'lumotsiz eksport va yuborishdan oldin qidirib ko'rish.
7. Mashqlar
1-mashq (oson): Formatlovchini tashqariga chiqaring
«Sekin menyuni profil bilan topamiz» bo'limidagi oynani «Tahrirlab ko'rish» bilan oching. formatPrice ni shunday o'zgartiringki, formatlovchi bir marta yaratilsin. «Menyuni chiz» ni bir necha marta bosib, "Oxirgi chizish" vaqtini oldingisi bilan solishtiring.
Yechim
const formatter = new Intl.NumberFormat("uz", {
style: "currency", currency: "UZS", maximumFractionDigits: 0,
});
function formatPrice(price) {
return formatter.format(price);
}Formatlovchi skript yuklanganda bir marta yaratiladi, formatPrice esa faqat format ni chaqiradi. Bizning o'lchovimizda vaqt taxminan 43 ms dan 7 ms ga tushdi. Profilni qayta yozing: Bottom-Up'da formatPrice endi pastda, birinchi o'rinlarda DOM ishi (replaceChildren) va brauzerning o'z ishi.
2-mashq (o'rta): Siljish aybdorini toping
Performance API va Core Web Vitals darsidagi chegirma banneri misolini (CLS 0.073) yangi tabda oching. Performance panelida Record and reload qiling. Layout shifts qatoridagi binafsha rombni bosing va javob bering: qaysi elementlar siljidi va siljishga nima sabab bo'ldi?
Yechim
Romb ustida (Summary yorlig'ida) siljigan elementlar ro'yxati chiqadi: h2 va uchta p.card — menyu. Siljish 800 ms atrofida, setTimeout callback'idan keyin. Insights'dagi "Layout shift culprits" esa sababni nomlaydi: DOM'ga kech qo'shilgan element (banner). Biz shu natijani o'lchovda ham olgan edik: entry.sources ro'yxatida H2 va P.card lar. Tuzatish — o'sha darsdagi #top { min-height: 8rem; }.
3-mashq (qiyin): Network'da sekin internetni sinang
Live Server bilan vazifalar ni oching. Network panelida:
- "Disable cache" ni yoqing va tarmoqni "Slow 4G" ga qo'ying.
- Sahifani yangilang. Waterfall'da: qaysi fayllar birga boshlanadi?
olchov.jsqachon keladi? - API so'roviga o'ng tugma → "Block request URL" qiling va sahifani yangilang. Ilova nima deydi?
Yechim
1–2. Modullar modulepreload tufayli bir vaqtda boshlanadi — waterfall'da ular bir-birining ostida, bir xil boshlanish nuqtasida. Sekin tarmoqda har biri uzoqroq yuklanadi, lekin "zinapoya" yo'q. olchov.js va vendor/web-vitals.js oxirida, asosiy.js ishlagandan keyin keladi — dinamik import().
- API bloklanganda
vazifalar11-qismdagi xulqni ko'rsatadi: ro'yxatlocalStoragekeshidan chiziladi, holat qatorida "Serverga ulanib bo'lmadi. Ro'yxat — shu brauzerdagi nusxa." va «Qayta urinish» tugmasi chiqadi. Network'da bloklangan so'rov qizil rangda, Status ustunida(blocked:devtools). Shu bir harakat bilan xato holatini serverga tegmasdan sinadingiz.
4-mashq: Vazifalar qadami — CLS'ni topib tuzatish
Performance API va Core Web Vitals darsida vazifalar CLS'ni yozdi: 0,139. Endi sababini topamiz va tuzatamiz — bitta atribut bilan.
1. O'lchash — Lighthouse 13.5.0, mobil. Bizning o'lchovlar (Chrome 154, ekransiz rejim, Lighthouse'ning standart mobil sozlamasi):
| Holat | Performance | LCP | CLS |
|---|---|---|---|
| v3.1 (12-qism oxiri) | 94 | 1,9 s | 0,143 |
| Web Vitals qadami (tuzatishdan oldin) | 91 | 2,3 s | 0,153 |
| Shu qadam (tuzatish) | 98 | 2,3 s | 0 |
Accessibility va SEO — hamma holatda 100. Best Practices v3.1 da 96 edi (/favicon.ico 404 xatosi), PWA qadamida ikonlar qo'shilgach — 100.
2. Sababni topish. Lighthouse'ning "Avoid large layout shifts" auditi aybdorni nomladi: textarea#eksport-matn, siljish 0,153. Performance panelida ham xuddi shu: Layout shifts qatorida bitta romb, birinchi chizishdan keyin.
Nega? index.html da ro'yxat bo'sh (<ul>), uni asosiy.js chizadi. Modul skriptlari esa sukut bo'yicha kechiktiriladi (defer kabi, Skriptlarni ulash). Brauzer sahifani bo'sh ro'yxat bilan bir marta chizadi. Keyin render() vazifalarni qo'yadi va ro'yxatdan pastdagi hamma narsa — forma, eksport maydoni — pastga suriladi.
3. Tuzatish — bitta atribut:
git switch -c fix/cls-siljish<!-- Oldin -->
<script type="module" src="assets/js/asosiy.js"></script>
<!-- Keyin -->
<script type="module" src="assets/js/asosiy.js"
blocking="render"></script>blocking="render" brauzerga aytadi: "shu skript yuklanib, bajarilmaguncha sahifani chizma". Natijada birinchi kadrdayoq ro'yxat joyida — siljish yo'q. Renderni nima to'xtatadi darsida bloklovchi resurslardan qochishni o'rgangan edik — bu yerda esa ongli ravishda bitta skriptni bloklovchi qildik.
Narxi bor va uni ochiq aytamiz. Lighthouse'ning "Render-blocking requests" bo'limiga endi asosiy.js ham qo'shildi (tejash taxmini 150 → 300 ms). Lekin vazifalar ning skriptlari kichik va keshlangan — FCP 1,5 → 1,6 s (shovqin chegarasida), CLS esa 0,153 → 0. Ballga CLS 25 foiz og'irlik bilan kirgani uchun natija 91 → 98.
4. Brauzer qo'llashi — muhim cheklov. blocking="render" Baseline emas. U Chrome va Edge'da 105-versiyadan bor; web-features ma'lumotiga ko'ra Safari'da 18.2 dan; Firefox'da yo'q (2026-oktabr). Biz uni faqat Chrome'da o'lchadik. Atributni tanimaydigan brauzer uni shunchaki e'tiborsiz qoldiradi: ilova ishlaydi, faqat ro'yxat birinchi kadrdan keyin chiziladi va CLS qaytadi. Kanon buni TEXNIK-QARZ.md ning 14-qatoriga yozadi; to'liq yechim — serverda tayyor HTML yoki joy ajratilgan skelet, keyingi qismlarda.
sw.js dagi VERSIYA oshirilmadi. Sabab — Kesh strategiyalari darsidagi network-first: yangi index.html baribir tarmoqdan keladi.
5. Tekshirish. Testlar 90/90 (mantiq o'zgarmadi). Brauzer tekshiruvi 103/103, yangi qator:
✅ #30: CLS — siljish yo'q: "[Web Vitals] CLS: 0.000 (yaxshi)"Oldingi darsdagi konsol qatori endi CLS: 0.000 (yaxshi). O'lchov → sabab → tuzatish → yana o'lchov — sikl yopildi.
6. Commit va PR. Sarlavha 72 belgidan oshmasin (Git qoidasi), tafsilot — tanada:
git add index.html
git commit \
-m "fix: ro'yxat birinchi kadrda chiziladi (blocking=\"render\")" \
-m "asosiy.js chizishni to'sadi: CLS 0.15 → 0"
gh pr create --fill
gh pr merge --mergeDiff: 1 fayl, +2 −1. Eng kichik diff — eng katta ball o'zgarishi. Profilsiz biz shu bitta qatorni topishimiz uchun soatlab taxmin qilgan bo'lardik.
8. Real ishda
- Performance budget. Jamoalar "LCP ≤ 2,5 s, JS ≤ 200 KB" kabi chegaralarni yozib qo'yadi va Lighthouse CI bilan har PR'da tekshiradi (CI — keyingi qismlarda).
- Bug hisobotlari. "Sekin" degan shikoyatga eng yaxshi javob — profil fayli. Performance paneli yozuvni faylga saqlaydi, uni hamkasbga yuborish mumkin.
- Sizish qidirish. Gmail, Telegram Web kabi soatlab ochiq turadigan ilovalarda Memory paneli va Performance monitor — kundalik vosita.
- Intervyu. "Sahifa sekin — qayerdan boshlaysiz?", "Flame chart qanday o'qiladi?", "Self va Total time farqi?", "Lighthouse balliga nima eng ko'p ta'sir qiladi?" — frontend intervyularida ko'p so'raladi.
Xulosa
- Tartib: o'lcha → profil yoz → sababni top → bitta o'zgarish → yana o'lcha. Profil CPU 4–6× sekinlashtirilgan holda yoziladi.
- Flame chart: kenglik — vaqt, bo'y — chaqiruvlar zanjiri, qizil burchak — uzun task; sekin joy — Bottom-Up'da Self time bo'yicha.
- Memory: heap snapshot (surat), allocations on timeline (qachon va nima tirik), allocation sampling (qaysi funksiya); "tishlar" ko'tarilsa — sizish.
- Network: waterfall — qachon, Initiator — kim, Priority — qanchalik muhim; request blocking bilan xato holatlarini sinash; HAR'da sir bo'lishi mumkin.
- Lighthouse balli: TBT 30, LCP 25, CLS 25, FCP 10, SI 10 foiz;
vazifalardablocking="render"CLS'ni 0,153 dan 0 ga tushirdi (91 → 98).
Keyingi dars: XSS va DOM xavfsizligi — tezlikdan xavfsizlikka: foydalanuvchi matni qanday qilib kodga aylanadi, uni qanday to'xtatamiz va vazifalar da XSS auditi.
Manbalar
- Chrome for Developers: "Performance panel: Analyze your website's performance", "Performance features reference" — developer.chrome.com/docs/devtools/performance
- Chrome for Developers: "Memory panel", "Network features reference" — developer.chrome.com/docs/devtools
- Lighthouse: "Lighthouse performance scoring" — developer.chrome.com/docs/lighthouse/performance/performance-scoring
- HTML Living Standard: "Blocking attributes" — html.spec.whatwg.org
Izohlar (0)
Izoh yozish uchun kiring.
- Hozircha izoh yo'q. Birinchi bo'ling!