Seriya: JavaScript Basics Dars 55

Reflow vs Repaint

Render tree ekranga chiqishdagi uch bosqich — Layout (Reflow), Paint (Repaint), Composite — va ularning narx farqi, har bosqichni keltirib chiqaruvchi CSS xususiyatlar, Layout Thrashing (Forced Synchronous Layout) xavfi, va uni oldini olish usuli.

55-dars

Reflow vs Repaint

Render tree tayyor bo'lgach, brauzer uni ekranga chiqarish uchun yana uchta bosqichdan o'tkazadi: Layout (Reflow) → Paint (Repaint) → Composite. Bu uchtasi — narx jihatidan teng emas. Ba'zi CSS o'zgarishlar hammasini qayta ishlatadi (qimmat), ba'zilari faqat oxirgisini (arzon).

  • Reflow (Layout) — har bir elementning aniq o'lchami va joylashuvi (X, Y koordinatalari, kengligi, balandligi) qayta hisoblanadi
  • Repaint (Paint) — hisoblangan joylashuv asosida, har bir element piksel darajasida chiziladi (rang, soya, chegara)
  • Composite — chizilgan qatlamlar (layer'lar) ekranga birlashtirilib qo'yiladi

1. Nega ikkovi ajratilgan — bitta jarayon bo'lsa bo'lmaydimi?

Sabab — narx farqi. Joylashuvni hisoblash (Reflow) — butun daraxt bo'ylab zanjirli ta'sir qiladi, chunki bitta elementning kengligi o'zgarsa, uning yonidagi, ostidagi barcha elementlar ham joyini o'zgartirishi mumkin (xuddi domino effekti kabi). Rangni o'zgartirish esa (Repaint) — joylashuvga umuman ta'sir qilmaydi, faqat "shu joyni boshqa rangda qayta chiz" degani, ancha arzon.

Brauzer dizaynerlari shuni tushunib: agar har bir CSS o'zgarishda to'liq joylashuvni qayta hisoblasa — juda sekin bo'lardi. Shuning uchun ular CSS xususiyatlarini uchta toifaga ajratdilar, va har birida faqat kerakli bosqichdan boshlanadi.


2. Uch bosqich — brauzer darajasida nima sodir bo'ladi

1. Layout (Reflow)

element.style.width = '300px';

Bu — elementning geometriyasiga tegadi. Blink engine butun Render tree bo'ylab (yoki hech bo'lmasa, ta'sirlangan qism bo'ylab) yurib, har bir node uchun aniq X, Y, width, height qiymatlarini qaytadan hisoblaydi. Bu — CPU'da og'ir matematik hisoblash: har bir element o'z ota-elementiga, birodar elementlariga bog'liq (masalan, flexbox, grid hisob-kitoblari).

Reflow'ni keltirib chiqaruvchi narsalar:

  • width, height, padding, margin, border
  • display, position, top/left/right/bottom
  • Elementni DOM'ga qo'shish/olib tashlash
  • Oyna o'lchamini o'zgartirish (window resize)
  • Shrift o'lchamini o'zgartirish

2. Paint (Repaint)

Layout tugagach, brauzer har bir elementni piksel darajasida chizadi — qaysi rangda, qaysi soya bilan, qaysi chegara bilan. Bu — Layout'dan arzonroq, chunki koordinatalar allaqachon aniq, faqat "shu joyni shu rangda bo'ya" degan amal.

Faqat Repaint keltirib chiqaruvchi narsalar (joylashuv o'zgarmaydi):

  • color, background-color
  • visibility (eslatma: display: none — Reflow, visibility: hidden — faqat Repaint!)
  • box-shadow, outline

3. Composite

Zamonaviy brauzerlar sahifani bir nechta **qatlam (layer)**ga bo'ladi (masalan, position: fixed bo'lgan element, transform qo'llangan element — ko'pincha o'z alohida qatlamiga chiqariladi). Composite bosqichida bu qatlamlar GPU yordamida, to'g'ri tartibda ustma-ust qo'yilib, yakuniy tasvir hosil qilinadi.

Faqat Composite kerak bo'ladigan narsalar (eng arzon!):

  • transform (translate, scale, rotate)
  • opacity

Bu ikkovi — Layout'ni ham, Paint'ni ham chetlab o'tadi, to'g'ridan-to'g'ri GPU orqali, alohida qatlam sifatida qayta joylashtiriladi yoki shaffofligi o'zgartiriladi. Shuning uchun animatsiyalarda left/top o'rniga transform: translateX() ishlatish tavsiya qilinadi — natija bir xil ko'rinsa ham, narxi butunlay boshqacha.


3. Zanjirli ta'sir — nega Reflow eng qimmat

Layout o'zgardi → Paint albatta qayta ishlaydi (chunki joylashuv o'zgargan, eski rasm noto'g'ri) → Composite ham qayta ishlaydi

Ya'ni: Reflow → Paint → Composite hammasini ishga tushiradi. Lekin Composite yolg'iz — hech narsani ishga tushirmaydi (Layout ham, Paint ham qayta hisoblanmaydi). Shu sababli tezlik tartibi:

Reflow (eng qimmat) > Repaint (o'rtacha) > Composite (eng arzon)

4. V8/JS darajasida — "Layout Thrashing" degan xavfli holat

Bu joyda JS bilan brauzer engine orasidagi muvofiqlashtirish muhim bo'lib qoladi. Odatda brauzer DOM o'zgarishlarni darhol qayta hisoblamaydi — ularni to'playdi va bitta frame oxirida (taxminan har 16ms'da, 60fps uchun) bir martada Layout qiladi. Bu — optimallashtirish.

Lekin agar siz JS orqali DOM'ni o'zgartirib, keyin shu zahoti geometriya so'rasangiz — brauzer to'plangan o'zgarishlarni majburiy, sinxron ravishda hisoblab berishga majbur bo'ladi (bu "Forced Synchronous Layout" deyiladi):

// YOMON: har iteratsiyada Forced Reflow
for (let i = 0; i < boxes.length; i++) {
  boxes[i].style.width = boxes[i].offsetWidth + 10 + 'px';
  // .offsetWidth O'QISH — bu brauzerni "hoziroq Layout qil" deb majburlaydi,
  // chunki eski, to'plangan qiymat noto'g'ri bo'lishi mumkin
}

Bu yerda muammo: .style.width = ... (yozish) va .offsetWidth (o'qish) navbatma-navbat, har iteratsiyada aralashtirilgan. Brauzer har safar "yoz → oldingi yozuvlar asosida joylashuvni hoziroq hisobla → o'qi" qilishga majbur bo'ladi — bu "Layout Thrashing" deb ataladi, va sahifa sezilarli darajada sekinlashadi (ayniqsa, ko'p elementlar bilan loop ichida).

To'g'ri yechim — avval hamma o'qishlarni, keyin hamma yozishlarni alohida qilish:

// YAXSHI: avval o'qi, keyin yoz — bitta Reflow yetarli
const widths = boxes.map(box => box.offsetWidth); // hammasini o'qib olamiz
boxes.forEach((box, i) => {
  box.style.width = widths[i] + 10 + 'px'; // hammasini yozamiz
});

Bu — brauzerga bitta, yig'ma Reflow qilish imkonini beradi, har iteratsiyada emas.


Xulosa jadvali

Bosqich Nima hisoblanadi Narxi Misol xususiyat
Layout (Reflow) Joylashuv, o'lcham Eng qimmat width, top, display
Paint (Repaint) Piksel ranglari O'rtacha color, background
Composite Qatlamlarni birlashtirish Eng arzon (GPU) transform, opacity