IlmHamroh
JavaScript Full-stack/18-qism. React chuqur22/42-dars18 daqiqa
Mundarija (30)

Performance'ni o'lchash: Profiler va Performance Tracks

Qisqacha: Taxmin emas — o'lchov. React'da uch asosiy vosita bor. React DevTools Profiler — yozib olasiz va har commit uchun qaysi komponent qancha ms chizilganini ko'rasiz (flamegraph), "Why did this render?" sababini ham. Ikkinchisi <Profiler id onRender> — koddan o'lchov: actualDuration (shu commit'dagi haqiqiy ish) va baseDuration (memo'siz hammasini chizish taxmini). Performance Tracks (React 19.2) — Chrome Performance panelida Scheduler ⚛ (Blocking, Transition, Suspense, Idle) va Components ⚛ treklari. Production build'da ularning hech biri ishlamaydi — buning uchun react-dom/profiling. vazifalar da 10 000 vazifa bilan bitta katak: actualDuration 8.8 ms, baseDuration 54.8 ms — memo ishini raqamda ko'ramiz.

Bu darsda

  • React DevTools Profiler'da yozib olish, commit tanlash, flamegraph va ranked ko'rinishini o'qiysiz.
  • <Profiler> API'si va onRender argumentlarini (phase, actualDuration, baseDuration) ishlatasiz.
  • Chrome Performance panelidagi React treklarini taniysiz.
  • Production'da o'lchash uchun profiling build yasaysiz.
  • react-scan va why-did-you-render qachon foydali ekanini bilasiz.

Oldin bilishingiz kerak: React DevTools bilan ishlash, Qayta render sabablari va miflar, memo, useMemo, useCallback, Core Web Vitals.

1. Nega bu kerak?

Oxirgi olti darsda biz ko'p raqam ishlatdik: 18 056 render, 48 ms, 264 ms, 6.6 KB. Ularni kanondagi maxsus skriptlar o'lchagan — puppeteer, React DevTools hook'ining o'rinbosari, Event Timing. O'quvchi sifatida siz har safar shunday skript yozmaysiz. Kundalik ishda "nega sekin?" savoliga javob — standart vositalar.

Ikkinchi sabab: "sekin" bir necha xil bo'ladi. Render uzoq (komponentlar ko'p yoki og'ir). Commit uzoq (DOM katta). Paint uzoq (CSS va joylashuv). Yoki React umuman aybdor emas — asosiy oqimni boshqa skript band qilgan. Har biriga boshqa davo, va davolashdan oldin qaysi biri ekanini aniq bilish kerak.

Hayotiy o'xshatish: Jasur aka "oshxonada buyurtma sekin chiqyapti" deydi. Sabab oshpazdami, ofitsiantdami yoki kassadami? Har bosqichni soat bilan o'lchamaguncha, kimni o'rgatish kerakligini bilmaysiz. Profiler — o'sha soat.

2. React DevTools Profiler

2.1 Yozib olish

React DevTools darsida Profiler yorlig'iga bir ko'z tashlagan edik. Endi tartib bilan:

  1. Settings → Profiler: "Record why each component rendered while profiling" ni yoqing.
  2. Profiler yorlig'ida ko'k doira — yozishni boshlang.
  3. Ilovada bitta harakat qiling (bitta bosish, bitta harf).
  4. Doirani qayta bosing — to'xtating.

Bitta harakat — bitta yozuv. Uzoq yozuvda o'nlab commit aralashib ketadi va asosiysini topish qiyin bo'ladi.

2.2 Commit'lar va flamegraph

Yuqori o'ng burchakda — ustunlar qatori: har ustun bitta commit (Render va commit). Ustun balandligi — shu commit'ning davomiyligi, rangi — sariq (uzoq) dan ko'k-yashil (qisqa) gacha. Bitta katak bosilganda vazifalar da beshta ustun bo'ladi — optimistik yangilanish, server javobi, tasdiq (Qayta render sabablari dagi "5 commit").

Ustunni tanlang — pastda shu commit'ning flamegraphi (alanga grafigi) chiqadi: komponentlar daraxti gorizontal chiziqlar ko'rinishida. Ota tepada, bolalar ostida. O'qish qoidasi:

Ko'rinish Ma'nosi
chiziq kengligi komponent va bolalarini chizish vaqti
sariq / to'q rang ko'p vaqt oldi
ko'k-yashil kam vaqt oldi
kulrang, chiziqli shu commit'da chizilmadi ("Did not render")

memo ishlayotganini flamegraph'da darhol ko'rasiz: memo, useMemo, useCallback dagi holat 20 da katak bosilganda 1 000 qatordan bittasi rangli, qolganlari kulrang.

2.3 Ranked va "Why did this render?"

Ranked (tartiblangan) ko'rinish — o'sha commit'dagi komponentlar faqat o'z vaqti bo'yicha (bolalarisiz), eng sekini tepada. "Qaysi bitta komponent og'ir?" savoliga eng tez javob shu.

Komponentni bosing — o'ng panelda:

  • "Why did this render?" — Qayta render sabablari dagi uchta sababdan biri: "The parent component rendered.", "• Hook 1 changed", "• Context changed". Yana "• Props changed:" (yonida props nomi) va birinchi chizishda "This is the first time the component rendered." chiqishi mumkin.
  • "Rendered at" — yozuv davomida bu komponent qaysi commit'larda chizilgani. Bitta harakatda 5 marta chizilgan komponent — shubhali.

Sozlamalardagi yana bir foydali joy — "Hide commits below N ms": mayda commit'larni yashirib, katta ishni topish oson.

Tekshirib ko'ring: Flamegraph'da VazifaRoyxati sariq va keng, uning ostidagi 1 000 qatorning hammasi rangli. Ranked'da eng tepada AmalTugmasi — har biri 0.1 ms. Muammo AmalTugmasi dami?

Javob

Yo'q. Bitta AmalTugmasi arzon, muammo — soni: 2 000 ta tugma × 0.1 ms. Ranked ko'rinishi har komponentni alohida ko'rsatgani uchun "eng sekin" deyarli teng mayda bo'laklarga bo'linib ketadi. Flamegraph esa butun ro'yxat qismi og'irligini ko'rsatadi. Savol "nega 1 000 qator chizildi?" — ya'ni VazifaQatori ning "Why did this render?" ga qarash kerak.

3. <Profiler> API

3.1 Koddan o'lchash

DevTools — qo'lda. Testda, CI'da yoki foydalanuvchi kompyuterida o'lchash uchun React'da komponent bor: <Profiler> — daraxtning bir qismini o'raydi va har commit'da onRender funksiyasini chaqiradi.

jsx
import { Profiler, useState } from "react";

function onRender(id, phase, actualDuration, baseDuration) {
  console.log(id, phase, actualDuration >= 0, baseDuration >= 0);
}

function Menu({ count }) {
  return <p>Buyurtmalar: {count}</p>;
}

function App() {
  const [count, setCount] = useState(0);
  return (
    <Profiler id="App" onRender={onRender}>
      <button onClick={() => setCount(count + 1)}>+1</button>
      <Profiler id="Menu" onRender={onRender}>
        <Menu count={count} />
      </Profiler>
    </Profiler>
  );
}

Konsolda:

text
Menu mount true true
App mount true true
Menu update true true
App update true true

Vaqtlarni konsolga son sifatida chiqarmadik: ular har kompyuterda va har urinishda boshqacha. Bu yerda faqat ular borligi va manfiy emasligi ko'rinadi. «Ishga tushir» da console.log(id, phase, actualDuration) deb o'zgartirib ko'ring — o'z kompyuteringiz raqamlarini ko'rasiz.

Ikki narsaga e'tibor bering. Birinchisi — tartib: ichki Menu oldin, tashqi App keyin, xuddi effektlardagidek (bola → ota). Ikkinchisi — Profiler ichma-ich bo'lishi mumkin: har biri o'z qismini o'lchaydi.

3.2 onRender argumentlari

Argument Ma'nosi
id <Profiler id> dagi nom
phase "mount" (birinchi), "update" yoki "nested-update"
actualDuration shu commit'da o'ralgan daraxtni chizishga ketgan ms (memo bilan o'tkazilganlar kirmaydi)
baseDuration hamma komponentlarning oxirgi render vaqtlari yig'indisi — memo siz chizilsa, qancha ketardi
startTime, commitTime render boshlangan va commit qilingan payt (performance.now() shkalasi)

Eng foydali juftlik — actualDuration va baseDuration. Ular yaqin bo'lsa — daraxt deyarli to'liq qayta chizilgan. actualDuration ancha kichik bo'lsa — memo yoki kompozitsiya ishni tejagan. Farq — tejalgan ish.

3.3 nested-update

Uchinchi faza — nested-update: commit tugashi bilan useLayoutEffect (yoki ref callback) ichida setState chaqirilsa, React yangi renderni darhol, paint'dan oldin bajaradi (useLayoutEffect). Bu ikkinchi commit sinxron, foydalanuvchi esa birinchisini ko'rmaydi:

jsx
import { Profiler, useLayoutEffect, useState } from "react";

function onRender(id, phase) {
  console.log(id, phase);
}

function Price({ value }) {
  const [label, setLabel] = useState("");
  useLayoutEffect(() => {
    setLabel(`${value} so'm`); // ❌ hosilaviy qiymat effektda
  }, [value]);
  return <p>{label}</p>;
}

function App() {
  return (
    <Profiler id="Price" onRender={onRender}>
      <Price value={35000} />
    </Profiler>
  );
}

Konsolda:

text
Price mount
Price nested-update

Birinchi chizishda ikki commit: avval bo'sh <p>, keyin matn bilan. nested-update — Profiler'dagi ogohlantiruvchi belgi: "bu yerda qo'shimcha sinxron commit bor". Ba'zan u zarur (DOM o'lchab, tooltip joylashtirish), lekin bu misolda emas — label render paytida hisoblanadi (Sizga effekt kerak emas). Tuzatish — 3-mashqda.

3.4 Production'da ishlamaydi

<Profiler> ning onRender i faqat dev build'da va maxsus profiling build'da chaqiriladi. Oddiy production build'da React vaqt o'lchash kodini butunlay olib tashlaydi — onRender jim, xarajat ham nol. Shuning uchun <Profiler> ni kodda qoldirish xavfsiz.

Lekin dev build ham o'lchov uchun yomon: u production'dan bir necha barobar sekin (qo'shimcha tekshiruvlar, StrictMode). Haqiqiy raqam uchun — production'ning o'zi, lekin profiling yoqilgan. react-dom paketida buning uchun alohida kirish bor: react-dom/profiling (React 19.3.0 da cjs/react-dom-profiling.profiling.js). Uni qanday ulash — «Vazifalar qadami» da.

4. Chrome Performance Tracks

4.1 React 19.2 dagi yangilik

Chrome DevTools'ning Performance paneli butun brauzerni yozadi: JavaScript, uslub hisobi, layout, paint, tarmoq (Core Web Vitals). Uzoq vaqt React u yerda faqat "qandaydir JavaScript funksiyalari" bo'lib ko'rinardi. React 19.2 (2025-10-01) panelga o'z treklarini qo'shdi — Performance Tracks.

Ular dev build'da va profiling build'da yoziladi (console.timeStamp orqali). Ikki guruh:

  • Scheduler — React nima bilan band: qaysi ustuvorlikda ish ketyapti.
  • Components — qaysi komponent qancha vaqt chizildi (flamegraph'ning vaqt chizig'idagi ko'rinishi).
flowchart TD
  P["Chrome Performance paneli"] --> S["Scheduler ⚛"]
  P --> C["Components ⚛"]
  S --> B["Blocking: bosish, yozish"]
  S --> G["Gesture"]
  S --> T["Transition: startTransition, Action"]
  S --> SU["Suspense: qayta urinish"]
  S --> I["Idle"]
  C --> K["Komponentlar: render vaqti"]

Diagrammadagi Scheduler ⚛ bolalariga qarang — bu Reconciliation darsidagi lanes guruhlari. react-dom 19.3.0 kodida trek nomi yo'lak bitlaridan tanlanadi: lanes & 63 — "Blocking", & 64 — "Gesture", transition yo'laklari — "Transition", retry yo'laklari — "Suspense", oxirgilari — "Idle".

4.2 Trekdagi hodisalar

Kanondagi o'lchov skripti (olchov/profil.mjs) Chrome trace'idan React yozgan hodisalarni yig'di (natijalar/22-profil.txt, katak bosilganda; faylda bir qatorda, bu yerda telefon uchun bo'lindi). Har qator — bitta trek: / dan oldin guruh, keyin trek nomi, ikki nuqtadan keyin shu trekdagi hodisalar:

text
Scheduler ⚛/Blocking: Blocking Track, Event: click, Update,
  Render, Commit, Waiting, Remaining Effects, Waiting for Paint
Scheduler ⚛/Transition: Transition Track, Event: click, Action,
  Prewarm, Suspended, Render, Commit, Waiting for Paint,
  Remaining Effects, Update Blocked
Scheduler ⚛/Suspense: Suspense Track
Scheduler ⚛/Idle: Idle Track
/Components ⚛: VazifaRoyxati, VazifaQatori, OddiyQator, Qator,
  BelgilanganMatn, AmalTugmasi

Bitta katak bosish — ikki trekda ish:

  • Blocking: Event: click → Update → Render → Commit → Waiting for Paint. Bu — useOptimistic ning darhol ko'rinadigan yangilanishi (useOptimistic).
  • Transition: Action (server so'rovi kutilmoqda), Prewarm (Suspense ichidagi oldindan render, Suspense), Render, Commit. Bu — tasdiq va startTransition qismi.

Bu bitta rasm 18-qismning birinchi o'n darsini birlashtiradi: concurrent rendering, Actions, Suspense — hammasi o'z trekida, millisekund aniqlikda.

Tekshirib ko'ring: Qidiruvga harf yozildi, Blocking trekida Render 2 ms, Transition trekida esa 250 ms. Foydalanuvchi qotishni sezadimi?

Javob

Odatda yo'q. Blocking — shoshilinch yangilanish (harf maydonga chiqdi) va u 2 ms. 250 ms lik transition renderi bo'laklarda ketadi va yangi harf kelsa to'xtaydi (Concurrent rendering). INP shoshilinch javobga qaraydi. Lekin Transition trekida bitta uzun bo'linmagan blok bo'lsa (bitta og'ir komponent), u ham bosishlarni ushlab turadi — shunda u ham davolanishi kerak.

5. Boshqa vositalar

Vosita Nima qiladi Qachon
react-scan sahifada qayta chizilgan komponentlarni ramka bilan, son va vaqt bilan ko'rsatadi "nima ko'p chizilyapti?" — DevTools ochmasdan, tez
why-did-you-render "oldini olish mumkin bo'lgan" renderlarni (props mazmunan o'sha, havola boshqa) konsolga yozadi memo buzilishini ov qilish
web-vitals onINP haqiqiy foydalanuvchilardagi INP production monitoring (Core Web Vitals)
Event Timing API har bosish va harfning to'liq kechikishi avtomatik o'lchov skriptlari (kanon katak-tezligi.mjs)

react-scan va why-did-you-render — uchinchi tomon kutubxonalar: ular React ichiga ulanadi, shuning uchun har React yangilanishida ularning qo'llab-quvvatlashini (CHANGELOG, peer) tekshiring (React 18 dan 19 ga darsidagi peer saboqlari). Ikkalasi faqat dev uchun — production bundle'ga kirmasin.

vazifalar da web-vitals 17-qismdan beri bor: olchov.ts alohida chunk bo'lib yuklanadi va INP, CLS, LCP ni yozadi.

6. Vazifalar qadami: profiling build va <Profiler> (holat 22)

6.1 Reja

Yangi branch: build/profil. Maqsad: production bilan bir xil, lekin <Profiler> va Performance Tracks ishlaydigan build — npm run build:profil. Oddiy build'ga hech qanday ta'sir yo'q. Diff: 8 fayl, +53 −6.

6.2 vite.config.ts: ikki joy

ts
    resolve: {
      alias: {
        // npm run build:profil (18/#22): react-dom'ning
        // profiling build'i — <Profiler onRender> va Performance
        // panelidagi React treklari production'da ham. Oddiy
        // build'ga ta'sir qilmaydi
        ...(mode === "profil"
          ? { "react-dom/client": "react-dom/profiling" }
          : {}),
ts
    build: {
      // profil build alohida papkaga — dist/ (deploy) bilan
      // aralashmasin
      outDir: mode === "profil" ? "dist-profil" : "dist",
ts
        output: {
          // profil build: funksiya nomlari saqlanadi —
          // Performance panelidagi "Components ⚛" trekida "It, Nt"
          // emas, "App, VazifaQatori" (18/#22; o'lchandi). Oddiy
          // build'da — yo'q
          keepNames: mode === "profil",

Izohlar telefon uchun qayta bo'lindi, kod — aynan. Uch qaror bor.

  • Alias — vite --mode profil (Vite III: env va rejimlar) bo'lsa, import { createRoot } from "react-dom/client" aslida react-dom/profiling dan oladi. Ilova kodi o'zgarmaydi.
  • dist-profil/ — alohida papka: profil build tasodifan deploy bo'lmasin. .gitignore, .prettierignore va ESLint globalIgnores ga ham qo'shildi.
  • keepNames — minifikatsiya funksiya nomlarini qisqartiradi. Kanon buni o'lchab topdi: usiz Components ⚛ trekida It, Nt, Mt, jt — o'qib bo'lmaydi. Narxi: profil bundle 272 → 343 KB (faqat profil build'da).

package.json:

json
    "build:profil": "tsc -b && vite build --mode profil",

.env.profil — production bilan bir xil API manzili, izohda nima uchun ekani.

6.3 profil.ts va App.tsx

ts
import type { ProfilerOnRenderCallback } from "react";

export const chizildi: ProfilerOnRenderCallback = (
  id,
  faza, // "mount" | "update" | "nested-update"
  haqiqiy, // actualDuration: shu commit'da daraxtni chizish (ms)
  asosiy, // baseDuration: memo'siz hammasini chizish taxmini (ms)
  boshlandi, // startTime
) => {
  performance.measure(`⚛ ${id} ${faza}`, {
    start: boshlandi,
    duration: haqiqiy,
    detail: { haqiqiy, asosiy },
  });
};

onRender natijasini konsolga emas, User Timing ga yozadi: performance.measure (Performance API). Afzalligi ikki tomonlama. Chrome Performance panelida o'lchov "Timings" yo'lagida React treklari yonida ko'rinadi. Avtomatik skript esa performance.getEntriesByType("measure") bilan o'qiydi — console.log ni parse qilish shart emas. ProfilerOnRenderCallback — @types/react dagi tayyor tur (React + TS II).

App.tsx da — ro'yxat <Profiler> bilan o'raldi:

tsx
            {/* Profiler (18/#22): ro'yxat qancha vaqt chizildi —
                faqat dev va build:profil'da o'lchaydi (profil.ts) */}
            <Profiler id="royxat" onRender={chizildi}>
              <VazifaRoyxati
                vazifalar={korinadigan}
                sorov={sorov}
                tahrirId={tahrirId}
              />
            </Profiler>

6.4 O'lchov

olchov/profil.mjs — profil build'da, Chrome headless (natijalar/22-profil.txt):

1 000 vazifa 10 000 vazifa
ochilish (mount): haqiqiy / asosiy 21.8 / 9.6 ms 163.4 / 52.7 ms
katak, 1-commit: haqiqiy / asosiy 1.3 / 9.2 ms 8.8 / 54.8 ms
katak, 2- va 3-commit: haqiqiy 0.4 va 0.4 ms 3.8 va 2.0 ms
qidiruv "v" (hamma qator): haqiqiy / asosiy 31.2 / 28.1 ms 285.4 / 242.7 ms
10 000 vazifa, ro'yxat Profiler'i: haqiqiy va asosiy vaqt
  • katak — haqiqiy (actual)8,8 ms
  • katak — memo'siz taxmin (base)54,8 ms
  • qidiruv "v" — haqiqiy285,4 ms
  • qidiruv "v" — taxmin242,7 ms

Manba: O'lchandi: vazifalar holat 22, npm run build:profil (react-dom/profiling), olchov/profil.mjs, Chrome headless, 2026-10-13 (natijalar/22-profil.txt)

Jadvalni o'qishda bitta ogohlantirish: ochilishdagi juftlikni solishtirmang. asosiy — "qayta chizish" taxmini, ochilish esa birinchi yaratish (DOM elementlari ham yasaladi). Solishtirish faqat yangilanishlarda (katak, qidiruv) ma'noli.

Uchta xulosa:

  1. Katak: 8.8 ms o'rniga 54.8 ms bo'lardi. asosiy — memo siz hammasini chizish taxmini. Haqiqiy ish 6 barobar kam — holat 20 dagi memo(VazifaQatori) ning hissasi, endi production build'da o'lchangan. memo darsidagi render soni (18 056 → 68) — o'sha natijaning boshqa o'lchovi.
  2. Qidiruv "v": haqiqiy ≥ asosiy. Hamma qator haqiqatan o'zgaradi (har birida belgilangan matn) — tejaydigan narsa yo'q. Bu yerda memo emas, boshqa vosita kerak: kamroq qator chizish.
  3. Ochilish: 10 000 vazifada 163 ms — faqat ro'yxatning render qismi, 50 087 DOM elementi bilan. Bu ham "kamroq qator chizish" muammosi.

Ikkala oxirgi xulosa — bitta yechimga ishora: ekranda ko'rinmaydigan qatorlarni umuman chizmaslik. Bu Virtualizatsiya — keyingi dars.

6.5 Tekshiruvlar va commit

Build, test, lint, format:check, tip — toza (natijalar/tekshiruv-22.txt); oddiy build hajmi o'zgarmadi (<Profiler> production'da jim). Brauzer: 159/159.

text
build: npm run build:profil — react-dom/profiling, <Profiler> o'lchovi

7. Ko'p uchraydigan xatolar

Belgi Sabab Davosi
onRender production'da chaqirilmaydi oddiy build'da profiling o'chirilgan react-dom/profiling alias bilan alohida build
dev'da o'lchangan raqamlar qo'rqitadi dev build sekinroq, StrictMode ikki marta profil build yoki production'da o'lchang
Components trekida It, Nt minifikatsiya nomlarni qisqartirgan profil build'da keepNames
Profiler yozuvi tushunarsiz, o'nlab commit bir yozuvda ko'p harakat bitta harakat — bitta yozuv
nested-update har commit'da layout effektda setState hosilaviy qiymat — render paytida
"eng sekin komponent" mayda, lekin ko'p ranked faqat o'z vaqtini ko'rsatadi flamegraph'da butun qismga qarang

8. Mashqlar

Mashqlar kurs/mashqlar/18/22-profiler/ da. Har yechimni «Ishga tushir» bilan sinang.

1-mashq (oson): qaysi vosita?

  • "Bitta bosishda qaysi komponent necha ms oldi?":
  • "Haqiqiy foydalanuvchilarda INP qancha?":
  • "Transition kutildimi yoki bosishni bloklayaptimi?":
  • "Komponent nega chizildi?":
Yechim

React DevTools Profiler — commit va komponent vaqtlari. web-vitals (onINP) — production'dagi haqiqiy foydalanuvchilar. Performance Tracks — React ishini brauzerning boshqa ishi bilan bitta vaqt chizig'ida, ustuvorlik bo'yicha. "Why did this render?" — Profiler ichidagi sabab yozuvi.

2-mashq (o'rta): commit'larni sanash

OrderPanel ni <Profiler> bilan o'rang va onRender da har id uchun commit sonini hisoblang. «Hisobot» tugmasi bosilganda konsolga OrderPanel: N commit chiqsin (N — shu paytgacha). Ikki marta «+1», keyin «Hisobot» — kutilgan natija pastda.

jsx
import { useState } from "react";

function OrderPanel() {
  const [count, setCount] = useState(0);
  return (
    <div>
      <button onClick={() => setCount(count + 1)}>+1</button>
      <p>Buyurtmalar: {count}</p>
    </div>
  );
}

Konsolda (kutilgan):

text
OrderPanel: 3 commit
Yechim
jsx
import { Profiler, useState } from "react";

const commits = new Map();

function countCommit(id) {
  commits.set(id, (commits.get(id) ?? 0) + 1);
}

function OrderPanel() {
  const [count, setCount] = useState(0);
  return (
    <div>
      <button onClick={() => setCount(count + 1)}>+1</button>
      <p>Buyurtmalar: {count}</p>
    </div>
  );
}

function App() {
  function report() {
    for (const [id, n] of commits) console.log(`${id}: ${n} commit`);
  }
  return (
    <div>
      <Profiler id="OrderPanel" onRender={countCommit}>
        <OrderPanel />
      </Profiler>
      <button onClick={report}>Hisobot</button>
    </div>
  );
}

Konsolda:

text
OrderPanel: 3 commit

Uchta: birinchi chizish (mount) va ikki «+1» (update). «Hisobot» bosilishi state'ni o'zgartirmaydi — commit yo'q. Hisob Map da, komponentdan tashqarida. Uni state'da saqlash mumkin emas: onRender dagi har set… yangi commit chaqirib, cheksiz halqa bo'lardi.

3-mashq (qiyin): nested-update ni yo'qoting

«nested-update» bo'limidagi Price komponentini tuzating: birinchi chizishda bitta commit bo'lsin (Price mount), ekranda esa 35000 so'm.

Yechim
jsx
import { Profiler } from "react";

function onRender(id, phase) {
  console.log(id, phase);
}

function Price({ value }) {
  const label = `${value} so'm`; // ✅ render paytida hisoblanadi
  return <p>{label}</p>;
}

function App() {
  return (
    <Profiler id="Price" onRender={onRender}>
      <Price value={35000} />
    </Profiler>
  );
}

Konsolda:

text
Price mount

Ekranda:

text
35000 so'm

label — value dan hosil bo'ladigan qiymat. Uni state'da saqlash va effektda yangilash — ikki commit va bir lahzalik bo'sh <p> (layout effekt bo'lgani uchun ko'rinmaydi, lekin ish ikki barobar). Hisob arzon bo'lsa — shunchaki render paytida; qimmat bo'lsa — useMemo (memo, useMemo, useCallback).

4-mashq: vazifalar — o'z o'lchovingiz

build/profil branch'ida «Vazifalar qadami» dagi o'zgarishlarni kiriting va npm run build:profil qiling. dist-profil/ ni statik server bilan oching (masalan npx vite preview --outDir dist-profil), 1 000 vazifa bilan. Chrome DevTools → Performance → yozishni boshlang → bitta katakni bosing → to'xtating. Scheduler ⚛ va Components ⚛ treklarini toping. Konsolda: performance.getEntriesByType("measure").filter((m) => m.name.startsWith("⚛")) — detail dagi haqiqiy va asosiy ni yozing. Commit va PR.

Yechim

Raqamlar kompyuteringizga bog'liq, lekin nisbat kanondagidek bo'lishi kerak: katakda haqiqiy asosiy dan bir necha barobar kichik (kanonda 1 000 da 1.3 / 9.2 ms). Agar ular yaqin bo'lsa — memo(VazifaQatori) ishlamayapti (holat 20 ni tekshiring). Performance'da Blocking trekida Event: click, Transition trekida Action — server javobini kutish. Components ⚛ da nomlar o'qiladigan bo'lsa — keepNames ishladi. Commit xabari — «Tekshiruvlar va commit» bo'limida.

9. Real ishda

  • Performance budjeti: jamoalar "bitta bosish — 50 ms dan kam render" kabi chegara qo'yadi va profil build bilan CI'da o'lchaydi.
  • Bug hisobotlari: "sekin" degan hisobotga Performance yozuvi (.json trace) ilova qilinadi — React treklari bilan u to'liq hikoya.
  • Production monitoring: Sentry, Datadog kabi xizmatlar INP va long task'larni yig'adi; profil build esa faqat tahlil uchun, foydalanuvchiga emas.
  • Intervyu savollari: "React ilovasining sekin joyini qanday topasiz?", "actualDuration va baseDuration farqi?", "Production'da React'ni qanday profil qilasiz?", "Flamegraph'dagi kulrang nima?".

Xulosa

  • Davolashdan oldin o'lchang: render, commit, paint yoki boshqa skript — har biriga boshqa davo.
  • DevTools Profiler: bitta harakat — bitta yozuv; commit ustunlari, flamegraph (kulrang — chizilmadi), ranked, "Why did this render?".
  • <Profiler id onRender>: phase (mount/update/nested-update), actualDuration (haqiqiy) va baseDuration (memo'siz taxmin) — farqi tejalgan ish.
  • Performance Tracks (React 19.2): Scheduler ⚛ — Blocking/Gesture/Transition/Suspense/Idle (lanes guruhlari), Components ⚛ — komponent vaqtlari.
  • Production'da onRender va treklar yo'q — react-dom/profiling alias, alohida dist-profil, keepNames.
  • vazifalar 10 000: katak — haqiqiy 8.8 ms, taxmin 54.8 ms (memo hissasi); qidiruv "v" va ochilish — kamroq qator chizish kerak.

Keyingi dars: Uzun ro'yxatlar: virtualizatsiya — 10 000 qatordan faqat ekrandagi 15 tasini chizish: ochilish ~760 → ~170 ms.

Manbalar

  • React: <Profiler> — react.dev/reference/react/Profiler
  • React: "React Performance tracks" — react.dev/reference/dev-tools/react-performance-tracks
  • React 19.2 e'loni (2025-10-01) — react.dev/blog/2025/10/01/react-19-2
  • Chrome DevTools: Performance paneli — developer.chrome.com/docs/devtools/performance
  • react-dom 19.3.0 manba kodi: setCurrentTrackFromLanes — npm paketi
  • Kanon: sinov/18/QADAMLAR.md (#22), natijalar/22-profil.txt, olchov/profil.mjs, natijalar/tekshiruv-22.txt
Ulashish:Telegram'da

Izohlar (0)

Izoh yozish uchun kiring.

  • Hozircha izoh yo'q. Birinchi bo'ling!
Performance'ni o'lchash: Profiler va Performance Tracks — IlmHamroh