IlmHamroh
JavaScript Full-stack/13-qism. Brauzer API'lari, performans va xavfsizlik30/32-dars19 daqiqa
Mundarija (32)

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 vazifalar dagi 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"| B

Muhim 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:

  1. CPU throttling — protsessorni 4× yoki 6× sekinlashtirish. Kompyuteringiz telefondan ancha tez; sekinlashtirmasangiz, muammoni ko'rmay qolasiz.
  2. Network — sekin tarmoq (masalan, "Slow 4G").
  3. 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, click hodisasi), 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:

html
<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):

2 000 ta taomni chizish vaqti
  • 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 renderMenu ning 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.html dagi <link rel="modulepreload"> ning xizmati (Dinamik import() darsidagi g'oya). Busiz brauzer asosiy.js ni o'qib, keyin uning importlarini, keyin ularning importlarini — "zinapoya" bo'lib yuklardi.
  • olchov.js keyinroq. U 116 ms da — asosiy.js ishlagandan keyin, dinamik import() bilan. Biz buni ataylab qildik.
  • Preflight. API so'rovidan oldin OPTIONS qatori — 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 .har faylga saqlash. Backend dasturchiga "menda shunday bo'ldi" deb yuborish uchun.

Diqqat: HAR fayl ichida cookie'lar, Authorization sarlavhalari 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:

Lighthouse Performance balli: o'lchovlar og'irligi
  • 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:

bash
npx lighthouse@13.5.0 http://127.0.0.1:5500/ --view

npx 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
js
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:

  1. "Disable cache" ni yoqing va tarmoqni "Slow 4G" ga qo'ying.
  2. Sahifani yangilang. Waterfall'da: qaysi fayllar birga boshlanadi? olchov.js qachon keladi?
  3. 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().

  1. API bloklanganda vazifalar 11-qismdagi xulqni ko'rsatadi: ro'yxat localStorage keshidan 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:

bash
git switch -c fix/cls-siljish
html
<!-- 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:

text
✅ #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:

bash
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 --merge

Diff: 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; vazifalar da blocking="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
Ulashish:Telegram'da

Izohlar (0)

Izoh yozish uchun kiring.

  • Hozircha izoh yo'q. Birinchi bo'ling!
DevTools Performance, Memory va Network: sekinlik sababini profil bilan topish — IlmHamroh