IlmHamroh
JavaScript Full-stack/2-qism. Internet, veb va brauzer16/20-dars12 daqiqa
Mundarija (35)

Renderni nima to'xtatadi: render-blocking CSS, skriptlar va reflow

Qisqacha: Brauzer CSS fayl to'liq yuklanib bo'lmaguncha sahifani chizmaydi — bu render-blocking. Oddiy <script> tegi esa HTML o'qishni to'xtatadi — bu parser-blocking. defer atributi skriptni fonda yuklab, HTML o'qib bo'lingach bajaradi. Sahifa chizilgandan keyin o'lcham o'zgarsa — og'ir reflow, faqat rang o'zgarsa — yengilroq repaint, transform va opacity esa eng yengil composite bosqichini ishga tushiradi.

Bu darsda

  • CSS nega sahifa chizilishini to'xtatishini va FOUC nima ekanini tushuntirasiz.
  • Oddiy <script> HTML o'qishni qanday to'xtatishini bilasiz.
  • defer va async farqini ayta olasiz va har vaziyatga mosini tanlaysiz.
  • Reflow, repaint va composite o'zgarishlarni ajratasiz.
  • Layout thrashing nima ekanini va uni qanday oldini olish g'oyasini tushuntirasiz.

Oldin bilishingiz kerak: HTML'dan pikselgacha: Critical Rendering Path.

1. Nega bu kerak?

Oldingi darsda brauzerning konveyerini ko'rdik: DOM → CSSOM → render tree → layout → paint → composite. Endi ikki muammoga qaraymiz.

Birinchi muammo — oq ekran. Sayt ochilyapti, internet tez, fayllar kichik. Lekin ekran bir-ikki soniya bo'm-bo'sh turadi. Ko'pincha sababi — konveyerni to'xtatib qo'ygan fayl.

Ikkinchi muammo — qotish. Sahifa ochildi, lekin menyu ochilganda ekran "titraydi". Sababi — sahifa har o'zgarganda konveyerning og'ir qismi qayta ishlayapti.

O'xshatish: katta yo'ldagi svetofor. U kerak — usiz chorrahada avariya bo'lardi. Lekin svetofor noto'g'ri joyga qo'yilsa, butun ko'chani tirbandlik bosadi. Brauzerdagi "svetoforlar" ham kerakli, faqat ularni to'g'ri joylashtirish lozim.

2. CSS nega renderni to'xtatadi

2.1 CSS faylni ulash

Haqiqiy saytlarda CSS alohida faylda yoziladi va HTML'ga shunday ulanadi:

html
<head>
  <link rel="stylesheet" href="style.css">
</head>
  • <link> — tashqi faylni sahifaga ulovchi teg.
  • rel="stylesheet" — "bu fayl uslublar jadvali (CSS)" degani.
  • href="style.css" — fayl manzili. URL darsidagi nisbiy yo'l kabi.

Brauzer bu tegni uchratishi bilan style.css ni yuklashga so'rov yuboradi.

2.2 FOUC — uslubsiz miltillash

Tasavvur qiling, brauzer CSS'ni kutmasdan sahifani chizib yubordi. Foydalanuvchi oq fonda oddiy qora matnni ko'radi. Bir soniyadan keyin CSS keladi: fon to'q ko'k, sarlavha markazda, menyu yon tomonda. Hammasi birdan sakrab, joyini o'zgartiradi.

Bu hodisa FOUC (Flash of Unstyled Content — uslubsiz kontent miltillashi) deb ataladi. Xunuk ko'rinadi va foydalanuvchini chalg'itadi.

2.3 Brauzer tanlovi: kutish

FOUC bo'lmasligi uchun brauzer CSSOM to'liq tayyor bo'lguncha sahifani chizmaydi. Bunday faylni render-blocking (chizishni to'xtatuvchi) resurs deyiladi.

text
HTML o'qilyapti ... <link style.css> ... HTML davom etadi
                        │
                        └─ style.css yuklanmoqda ... CSSOM tayyor
                                                       │
Ekran: [ oq ] [ oq ] [ oq ] [ oq ] [ oq ] [ oq ] ──▶ [ sahifa ]

E'tibor bering: HTML o'qish davom etadi, faqat chizish kutib turadi. Oqibati oddiy — CSS fayl katta yoki sekin bo'lsa, oq ekran shuncha uzoq turadi.

Maslahat: Faqat chop etish (printer) uchun yozilgan CSS'ga media="print" qo'shilsa, u ekrandagi chizishni to'xtatmaydi: <link rel="stylesheet" href="chop.css" media="print">. Brauzer uni kerak bo'lganda qo'llaydi.

Tekshirib ko'ring: Brauzer CSS'ni kutmasdan chizsa nima bo'lardi? Nega u kutishni afzal ko'radi?

Javob

Sahifa avval uslubsiz chiziladi, CSS kelgach hamma narsa sakrab o'zgaradi — FOUC. Brauzer foydalanuvchiga "sakraydigan" sahifa ko'rsatgandan ko'ra, biroz kutib, bir marta to'g'ri chizishni afzal ko'radi.

3. Skript nega HTML o'qishni to'xtatadi

3.1 Skriptni ulash

JavaScript fayl HTML'ga <script> tegi bilan ulanadi:

html
<script src="app.js"></script>
  • <script> — "bu yerda JavaScript bor" degan teg.
  • src="app.js" — kod joylashgan fayl manzili.

JavaScript'ni 08-qismda o'rganamiz. Hozir bilishingiz kerak bo'lgani: skript sahifaga yangi matn qo'shishi, elementlarni o'chirishi yoki o'zgartirishi mumkin.

3.2 Parser-blocking

Brauzer HTML'ni yuqoridan pastga o'qiydi. Oddiy <script> tegiga yetganda u HTML o'qishni to'xtatadi. Skriptni yuklaydi, bajaradi va faqat keyin davom etadi.

Nega? Skript HTML'ga yangi narsa qo'shishi mumkin. Brauzer oldindan bilolmaydi: davom etsa-yu, skript keyin hamma narsani o'zgartirsa, ish behuda ketadi. Shuning uchun kutadi.

Bunday skriptni parser-blocking (tahlilni to'xtatuvchi) deyishadi. "Parser" — HTML'ni o'qib, DOM quruvchi qism.

text
HTML o'qilyapti ──▶ <script src="app.js">
                    ⏸ to'xtadi: yuklash ... bajarish
                                              │
                    HTML davom etadi ◀────────┘

3.3 Ikki oqibat

  1. Sekin ochilish. Skript <head> ichida bo'lsa, u yuklanib bajarilguncha <body> hali o'qilmagan. Ekran oq turadi.
  2. Hali yo'q element. Skript sahifadagi tugmani qidiradi. Lekin brauzer hali tugmagacha o'qimagan — DOM'da tugma yo'q. Natijada xato chiqadi ("Ko'p uchraydigan xatolar" bo'limida ko'ramiz).

Maslahat: Brauzerda yordamchi ham bor — preload scanner (oldindan ko'ruvchi). Asosiy o'qish to'xtab turganda u HTML'ning qolganini tez ko'zdan kechiradi va boshqa CSS, JS, rasm fayllarini oldindan yuklay boshlaydi. Shunday bo'lsa ham, bajarish navbat bilan bo'ladi.

4. defer va async: skriptni to'g'ri ulash

4.1 Uch usul

Skriptni HTML o'qishni to'xtatmaydigan qilib ulashning ikki atributi bor: defer ("keyinga qoldirish") va async ("mustaqil"):

html
<script src="app.js"></script>
<script src="app.js" defer></script>
<script src="app.js" async></script>

Ular qanday ishlashini vaqt chizig'ida ko'ring:

text
Oddiy:
HTML ────⏸ yuklash + bajarish ────▶ HTML davom etadi

defer:
HTML ─────────────────────────────▶ tugadi ─▶ bajarish
      └─ fonda yuklash ─┘

async:
HTML ──────────────⏸ bajarish ──▶ HTML davom etadi
      └─ fonda yuklash ─┘
Usul Yuklash Qachon bajariladi Tartib saqlanadimi
oddiy HTML'ni to'xtatadi darhol Ha
defer fonda HTML to'liq o'qilgach Ha, yozilgan tartibda
async fonda yuklanib bo'lishi bilan Yo'q, qaysi biri tez kelsa

4.2 defer — odatiy tanlov

defer skripti fonda yuklanadi. HTML to'liq o'qilib, DOM tayyor bo'lgach bajariladi. Bir nechta defer skript bo'lsa — HTML'da yozilgan tartibda ishlaydi.

Aniqrog'i, defer skriptlar DOMContentLoaded hodisasidan oldin bajariladi. Bu — brauzerning "HTML to'liq o'qildi, DOM tayyor" degan signali. Bu nomni DevTools II darsida Network panelining pastki qatorida ko'rasiz.

Sahifadagi tugmalar va elementlar bilan ishlaydigan skriptlarning deyarli hammasiga defer mos keladi.

4.3 async — mustaqil skriptlar uchun

async skripti ham fonda yuklanadi, lekin yuklanib bo'lishi bilan darhol bajariladi — HTML o'qishni bir lahza to'xtatib. Qaysi skript oldin yuklansa, o'sha oldin ishlaydi.

U hech narsaga bog'liq bo'lmagan skriptlar uchun: tashrif statistikasi (masalan, Google Analytics yoki Yandex Metrika), reklama kodi.

4.4 Qaysi birini tanlash?

flowchart TD
  S["Skript ulayapmiz"] --> Q{"Sahifa elementlari yoki boshqa skript kerakmi?"}
  Q -->|"Ha"| D["defer"]
  Q -->|"Yo'q, mustaqil"| A["async"]

Eski saytlarda yana bir usulni ko'rasiz: skriptni </body> yopilishidan oldin, sahifaning eng oxiriga qo'yish. U ham ishlaydi — brauzer skriptga yetganda HTML allaqachon o'qilgan bo'ladi. Lekin defer yaxshiroq: skript ancha oldin, fonda yuklana boshlaydi.

Zamonaviy "modul" skriptlari (type="module") o'zi defer kabi ishlaydi. Skript ulashning barcha usullarini Skriptlarni ulash: defer, async, module darsida amalda qilamiz.

Tekshirib ko'ring: kutubxona.js va unga tayanadigan slayder.js bor. Ikkalasiga async qo'yilsa, nima bo'lishi mumkin?

Javob

async tartibni saqlamaydi. slayder.js kichikroq bo'lib oldin yuklansa, u kutubxona hali yo'qligida ishga tushadi va xato beradi. Bog'liq skriptlarga defer kerak — u yozilgan tartibni saqlaydi.

5. Reflow, repaint va composite

5.1 Sahifa bir marta chizilib qolmaydi

Sahifa ochildi. Lekin u "o'lik rasm" emas: foydalanuvchi menyuni ochadi, yangi xabar keladi, tugma rangi o'zgaradi. Har o'zgarishda brauzer konveyerning bir qismini qayta ishlatadi. Qaysi qismini — o'zgarish turiga bog'liq.

5.2 Uch xil narx

Reflow — layout'ni qayta hisoblash. Element o'lchami yoki joyi o'zgarganda sodir bo'ladi. Eng qimmati, chunki bitta element o'zgarsa, qo'shnilari ham surilishi mumkin. Reflow'dan keyin albatta repaint va composite ham keladi.

O'xshatish: kitob javoni. Bitta kitob qalinlashsa, uning o'ng tomonidagi hamma kitob suriladi. Hammasini qayta joylashtirish kerak.

Repaint — qayta bo'yash. Faqat ko'rinish o'zgarganda: rang, fon, soya. Joylar o'zgarmaydi, shuning uchun reflow'dan yengilroq.

Composite — faqat qatlamlarni qayta yig'ish. Element o'z qatlamida surilsa yoki shaffoflashsa, brauzer layout ham, paint ham qilmaydi. Tayyor qatlamni GPU siljitadi. Eng arzoni.

text
width, height, margin, font-size ──▶ Reflow ─▶ Repaint ─▶ Composite
color, background-color, shadow ──────────────▶ Repaint ─▶ Composite
transform, opacity ─────────────────────────────────────▶ Composite
O'zgarish Nima bo'ladi Narxi
Kenglik (width), balandlik, chekka (margin) Reflow Og'ir
Shrift o'lchami yoki matn qo'shilishi Reflow Og'ir
Rang (color), fon rangi Repaint O'rtacha
transform (surish, kattalashtirish), opacity Composite Yengil

transform: translateX(50px) — elementni ko'rinishda 50 piksel o'ngga surish. Muhimi: layout nuqtai nazaridan element joyida qoladi, qo'shnilar surilmaydi. Shuning uchun reflow bo'lmaydi.

Brauzer oynasining o'lchami o'zgarganda ham reflow bo'ladi — butun sahifa yangi kenglikka qayta hisoblanadi.

5.3 Misol: tugmani surish

Sichqoncha ustiga kelganda tugma o'ngga surilishi kerak. Ikki yo'l:

css
/* ❌ margin o'zgaradi: har kadrda reflow */
.tugma:hover {
  margin-left: 50px;
}

/* ✅ transform: faqat composite */
.tugma:hover {
  transform: translateX(50px);
}
  • .tugma — tugma degan nomli elementlar.
  • :hover — "sichqoncha ustida turganda" degani.
  • /* ... */ — CSS izohi, brauzer uni o'qimaydi.

Ekranda natija bir xil. Lekin birinchi usulda brauzer har kadrda qo'shni elementlarni ham qayta hisoblaydi. Kuchsiz telefonda bu titrashga olib keladi.

Tekshirib ko'ring: Sarlavha rangi qoradan ko'kka o'zgardi. Reflow bo'ladimi?

Javob

Yo'q. Rang elementning o'lchami va joyiga ta'sir qilmaydi. Faqat repaint (va composite) bo'ladi.

6. Layout thrashing

6.1 Brauzer ishni yig'ib bajaradi

Brauzer aqlli: skript sahifani o'zgartirganda u layout'ni darhol qayta hisoblamaydi. O'zgarishlarni yig'ib boradi va keyingi kadr oldidan hammasini bir marta hisoblaydi.

O'xshatish: onangiz sizni bozorga yuboradi. Aqlli yo'l — ro'yxatni to'liq yozib, bir marta borish.

6.2 Majburiy layout

Endi skript o'zgartirishdan keyin darhol o'lchamni so'raydi: "bu kartaning balandligi hozir necha piksel?" Brauzer to'g'ri javob berishi uchun yig'ilgan o'zgarishlarni shu zahoti hisoblashga majbur. Buni majburiy sinxron layout (forced synchronous layout, forced reflow) deyishadi.

Bir marta bo'lsa — mayli. Lekin skript shuni ro'yxatdagi 100 ta karta uchun navbatma-navbat qilsa, brauzer 100 marta layout qiladi. Bu layout thrashing ("layout'ni titratish") deb ataladi. Bozor o'xshatishida — har bir mahsulot uchun alohida bozorga borib kelish.

6.3 Yechim g'oyasi: o'qish va yozishni ajratish

text
❌ Aralash — har karta uchun alohida layout:
   1-karta: balandligini o'qi → o'zgartir
   2-karta: balandligini o'qi → o'zgartir
   ... 100 marta layout

✅ Ajratilgan — bitta layout:
   1) Hamma kartalarning balandligini o'qib chiq
   2) Keyin hammasini o'zgartir

Bu g'oyani JavaScript kodida qanday yozishni Rendering pipeline va layout thrashing darsida amalda qilamiz. Hozir qoidani eslab qoling: avval hamma o'qishlar, keyin hamma yozishlar.

7. Ko'p uchraydigan xatolar

7.1 Skriptni <head> ga atributsiz qo'yish

Konsolda shunday qizil xato chiqadi:

text
Uncaught TypeError: Cannot read properties of null (reading 'addEventListener')

Tarjimasi: "Tutilmagan tur xatosi: null ning xususiyatlarini o'qib bo'lmaydi (addEventListener ni o'qiyotganda)".

Nega: skript sahifadagi tugmani qidirdi. Lekin skript <head> da — brauzer hali <body> gacha o'qimagan, tugma DOM'da yo'q. Qidiruv natijasi null — JavaScript'da "hech narsa" degani. addEventListener so'zi xato emas: skript "hech narsa"ga shu buyruqni bermoqchi bo'lgan.

Tuzatish: skriptga defer qo'shing:

html
<script src="app.js" defer></script>

7.2 Bog'liq skriptlarga async qo'yish

Eski saytlarda ko'p uchraydigan xato:

text
Uncaught ReferenceError: $ is not defined

Tarjimasi: "$ aniqlanmagan". $ — jQuery degan eski, lekin hali ko'p saytda ishlaydigan JavaScript kutubxonasining nomi. Uni kursda alohida o'rganmaymiz.

Nega: jQuery'ga tayanadigan skript jQuery'dan oldin yuklanib, ishga tushib ketdi. async tartibni kafolatlamaydi.

Tuzatish: bog'liq skriptlarga defer qo'ying — ular yozilgan tartibda bajariladi:

html
<script src="jquery.js" defer></script>
<script src="slayder.js" defer></script>

7.3 defer ni ichki skriptga qo'yish

Kod faylda emas, to'g'ridan-to'g'ri teg ichida yozilgan bo'lsa, defer ishlamaydi. U faqat src bilan ulangan skriptlarga ta'sir qiladi.

Tuzatish: kodni alohida .js faylga olib, src bilan ulang.

7.4 Animatsiyada width yoki margin ishlatish

Nega xato: har kadrda reflow bo'ladi. Kompyuterda sezilmaydi, arzon telefonda titraydi.

Tuzatish: surish va kattalashtirish uchun transform, paydo bo'lish va yo'qolish uchun opacity ishlating.

8. Mashqlar

1-mashq (oson): Skript uchun atribut tanlang

Har vaziyat uchun oddiy, defer yoki async dan birini tanlang:

  1. Sahifadagi tugmalarga ish biriktiradigan asosiy main.js.
  2. Tashriflar sonini sanaydigan, hech narsaga bog'liq bo'lmagan hisoblagich.js.
  3. Biri ikkinchisiga tayanadigan kutubxona.js va grafik.js.
Yechim
  1. defer — skript DOM tayyor bo'lgach ishlaydi, tugmalar allaqachon bor.
  2. async — mustaqil, tartib muhim emas, tezroq ishga tushgani yaxshi.
  3. Ikkalasiga defer — tartib saqlanadi: avval kutubxona, keyin grafik.

2-mashq (o'rta): Qaysi bosqich ishlaydi?

Har o'zgarish uchun eng og'ir qayta ishlaydigan bosqichni yozing (reflow, repaint yoki composite):

  1. Tugma fon rangi yashildan qizilga o'zgardi:
  2. Matn shrifti 16px dan 20px ga kattalashdi:
  3. Rasm transform bilan 30px chapga surildi:
  4. Oynaning kengligi o'zgartirildi:
  5. Menyu opacity bilan asta paydo bo'ldi:
Yechim
  1. Repaint — faqat rang, geometriya o'zgarmaydi.
  2. Reflow — harflar kattalashsa, matn ko'proq joy oladi va qo'shnilar suriladi.
  3. Composite — transform elementni o'z qatlamida suradi.
  4. Reflow — butun sahifa yangi kenglikka qayta hisoblanadi.
  5. Composite — opacity ham faqat qatlamda ishlaydi.

3-mashq (qiyin): Sekin sahifani tuzating

Jasurning sayti 3 soniya oq ekran bilan ochiladi. Uning <head> qismi:

html
<head>
  <script src="jquery.js"></script>
  <script src="slayder.js"></script>
  <script src="statistika.js"></script>
  <link rel="stylesheet" href="style.css">
</head>

slayder.js jQuery'ga tayanadi. statistika.js mustaqil.

  1. Oq ekran nega uzoq?
  2. <head> ni qayta yozing.
Yechim
  1. Uchta oddiy skript HTML o'qishni navbatma-navbat to'xtatadi. Har biri yuklanib bajarilguncha brauzer oldinga o'tmaydi. CSS esa eng oxirida yozilgan. Brauzerning oldindan ko'ruvchisi uni ertaroq topishi mumkin, lekin bunga tayanmaslik kerak: CSS'ni skriptlardan oldin yozish — ishonchli odat.

  2. Tuzatilgan variant:

html
<head>
  <link rel="stylesheet" href="style.css">
  <script src="jquery.js" defer></script>
  <script src="slayder.js" defer></script>
  <script src="statistika.js" async></script>
</head>

CSS tepada — uning yuklanishi darhol boshlanadi. jQuery va slayder — defer: HTML'ni to'xtatmaydi va tartib saqlanadi. Statistika — async: mustaqil.

9. Real ishda

  • Lighthouse ogohlantirishlari. Google'ning Lighthouse vositasi sahifani tekshirib, "Render-blocking requests" (chizishni to'xtatuvchi so'rovlar) va "Forced reflow" (majburiy reflow) kabi tavsiyalar beradi. Bu — aynan shu dars mavzulari. Lighthouse'ni DevTools II darsida ishga tushiramiz.
  • Freymvorklar. React kabi freymvorklar (sahifa qurish uchun tayyor asoslar — kursda alohida qism bor) DOM o'zgarishlarini o'zi yig'ib, bir yo'la qo'llaydi. Bu layout thrashing'ning oldini olishga yordam beradi.
  • Intervyu savoli: "defer va async farqi nima?" — frontend intervyularida eng ko'p beriladigan savollardan biri. "Reflow va repaint farqi?" ham tez-tez so'raladi.

Xulosa

  • CSS — render-blocking: CSSOM tayyor bo'lmaguncha brauzer chizmaydi, aks holda FOUC bo'lardi.
  • Oddiy <script> — parser-blocking: yuklanib bajarilguncha HTML o'qish to'xtaydi.
  • defer — fonda yuklaydi, HTML o'qilgach tartib bilan bajaradi. Ko'p hollarda to'g'ri tanlov.
  • async — fonda yuklaydi, tayyor bo'lishi bilan bajaradi; faqat mustaqil skriptlar uchun.
  • O'lcham o'zgarsa — reflow (og'ir), rang o'zgarsa — repaint, transform/opacity — faqat composite (yengil).
  • Layout thrashing'dan qochish qoidasi: avval hamma o'qishlar, keyin hamma yozishlar.

Manbalar

Keyingi dars: Brauzer xotirasi va xavfsizlik modeli — brauzer ma'lumotni qayerlarda saqlashini va saytlarni bir-biridan qanday himoya qilishini ko'ramiz.

Ulashish:Telegram'da

Izohlar (0)

Izoh yozish uchun kiring.

  • Hozircha izoh yo'q. Birinchi bo'ling!
Renderni nima to'xtatadi: render-blocking CSS, skriptlar va reflow — IlmHamroh