Перераспалюванне, перамальёвка, кампаунд: скількі коштуе браузеру кожна змянена настройка CSS
Выучыце, як HTML і CSS працуюць через DOM, CSSOM, распалоўванне элемента, апляву кольора і складанне зображэнняў, а таксама разумеце, чыраз што змены шырыны караюцца дорожэ, чым змены кольору, і як утрымацца ад працязных перераспалоўваў элемента.
Крыніцы: Browser Rendering Pipeline Explained: From HTML to Pixels + Reflow vs Repaint
Адзін рядок маркапа, напрыклад загалоўка, выглядае проста, але прыстрой перегляду выканае дужо больш заўсёды працы, перш чым тэкст стане пікселямі на экране. Розумеўшы гэтыя заўсёды, можна адпавесці на практычныя запитанні: чаму змена размеру элемента може споваліць сторанку, чаму анімацыі зазвычай пішучыся за дапамогою transform, чаму адна змена може паўзіць на дзесяткі іншых элементаў, і чаму інтэнсывная маніпуляцыя DOM выклікае перашкоды ў роботе інтерфейсу. Шэйдзер практычна паказвае кожны этап процесу адрасавання, а праз гэты модель раз'яснюе разлік межу reflow і repaint, а таксама прычыны, якія дапамагають падтрымваць высокую швалькість кадраў.
<h1>Hello World</h1>
Процес адрасавання ў кароткім відзоре
У сваёй сутнасі процес адрасавання — это процэс, які ператварае тры вида інпуту: маркап, стылі і скрыпты, у зображэнне, якое можа паказаць дысплей.
HTML + CSS + JavaScript
↓
Pixels
↓
Screen
Якща разбіліць гэты процес на адзінныя етапы, ён выглядае працоўна так:
Parse HTML
↓
Build DOM
↓
Parse CSS
↓
Build CSSOM
↓
Create Render Tree
↓
Calculate Styles
↓
Layout / Reflow
↓
Paint / Repaint
↓
Composite
↓
Pixels on Screen
Калі людзі говораюць пра тое, насколькі шыбкая стораніца практычна паказвае свой першы видны контэнт, яны зазвычай называюць гэты процес Critical Rendering Path. Памятайце, што цэў — модель, а не спецыфікацыя конкрэтнага двайчарога. Chrome, Firefox і Safari реалізуюць гэтыя етапы по-рознаму, а ў новейшых апдэтах яны прыпінаюць дзеяння на тых етапах, калі можуць падтвердзіць, што гэта непатрэбна. Модель застаецца дастаткова точной для аналізу прыдатності, што ўсё ж таки мае значэнне для повсякдзенной роботы з фронтэндам.
Этап 1: парсінг HTML у DOM
Усё пачынаецца з дакумента HTML, які вяртае сервер, напрыклад, з маленькай стораніцы з аднам заглавлём і адным параграфам:
<!DOCTYPE html>
<html>
<body>
<h1>Hello World</h1>
<p>Welcome to my website.</p>
</body>
</html>
Парсер чытае гэты маркап і стварае Document Object Model — дрэва з вузлаў, у якім кожны элемент і кожны фрагмент тексту мае свое месца. Дрэва дакумента, показанага вышэй, выглядае так:
HTML
<html>
│
└── body
│
├── h1
│ └── "Hello World"
│
└── p
└── "Welcome..."
DOM фіксуе, што знаходзится ў дакументе і як гэта размешчанне ёсць вяроўнавучае. Гэта таксама інтарфейс, з якім працуюць вашы скрыпты; таму вызов, падобны таму, што паказана вышэй, праходзіць па гэтым дрэва, каб знайсці вузел:
document.querySelector("h1");
Парсаванне ведзецца поступова. Браузер не чакае завершэння цэлага файла, прычыму пачынае ствараць вузлы, таму довгая стораніца можа пачаць атрыбутавацыю, калі рэшта ўсё яшчэ надходзіць.
Этап 2: парсаванне CSS у CSSOM
Толькі структура нічога не сказвае пра выгляд. Для гэтага браузеру патрэбны шаблоны стылю, такія як гэтыя два простыя правіла:
h1 {
color: blue;
font-size: 32px;
}
p {
color: gray;
}
CSS адаптуюцца ў другую структуру – CSS Object Model. Корыстны спосаб раздзелення гэтых двух структур – па пытанню, на якое кожна з іх дае адказ:
DOM
↓
"What exists on the page?"
CSSOM
↓
"How should those things look?"
Для атрыбутавання элемента неабходны адказы на оба пытанні. Самэй гэтага шаблоны стылю блакуруць процес атрыбутавання.
Этап 3: адзінаванне двух структур у дрэво атрыбутавання
Калі ў браузере ўжо є DOM і CSSOM, яны з’едынаюцца ў дрэво атрыбутавання.
DOM
+
CSSOM
↓
Render Tree
У дрэве атрыбутавання зберагаецца толькі тое, што насправды будзе атрыбутаванае, а таксама стылі, якія до яго застосовуюцца. Возьмімо гэты фрагмент:
<div>
<h1>Hello</h1>
<p>World</p>
</div>
Пасля з’едынавання гэта можна уявіць як дрэва з виднымі элементамі, якія несу інфармацыю пра своі стылі:
Render Tree
div
│
├── h1
│ ├── font-size: 32px
│ └── color: blue
│
└── p
└── color: gray
Усе, што не берае участка ў атрыбутаванні візуальных налаштаўвань, залишаецца без урахоўвання. Элемент з display: none узагалі не мае запису, што адрозніцаяся ад visibility: hidden: скрыты элемент все ж займае прастор, таму ён застаецца ў структуре і продалей берае участак у планаванні макету.
Этап 4: вычысленне вырахаваных стаяў
Далей браузер вырахоўвае фінальную, вырахаваную стаяў для кожнага элемента, які будзе атрыбутаваны. Рэальныя шаблоны стаяў маюць такія перакрытые правіла:
.card {
width: 300px;
}
.card p {
font-size: 16px;
}
Для кожнага элемента дварчык должен павольна развярнуць тры пытанні:
Which rules apply?
↓
Which rule wins?
↓
What is the final computed style?
Адпаведныя адказы означаюць застосоўванне всіх правіл рашэння CSS:
- каскадаванне
- спадчынацтва ад элементаў-родакоў
- спецыфічнасць селектара
- канвертаванне ў вырахаваныя значэння
- стаяў, якія залежаць ад запытанняў прасоў
Рэзультатам ёсць адна супаковка якостей на кожны элемент:
DOM + CSSOM
↓
Style Calculation
↓
Computed Styles
Этап 5: разметка, дзе выявляецца геаметрыя
У гэты момент браузер ведае, што паказваць і як гэта должна выглядаць. Але ён яшчэ не ведае, дзе будзе кожны элемент і якога ён розмяру. Адпаведныя адказы да гэтых пытанняў — задача разметкі, якая ператварае прастор адображэння на супаковку распаложаных касет:
Viewport
┌────────────────────────────┐
│ │
│ Header │
│ │
├──────────────┬─────────────┤
│ Sidebar │ Content │
│ │ │
│ │ │
└──────────────┴─────────────┘
Пад час разметкі двайнік вычыляе для кожной касеты ў дрэве адрабаткі:
- шырыню і высоту
- пазіцыю
- маржы і заполненне
- спрыяжэння кожной касеты з суседзямі і прадкамі
- вялікую геаметрыю стораніцы
MDN падсумоўвае гэты этап як выявленне розмяру і месца кожнага вузла ў дрэве адрабаткі. Паколькі касеты залежная адзінадзею, разметка ёсць проблемай для цэлага дрэва, а не для кожнага окремага элемента.
Рефлоу: паўтарычны расклад
Першы этап обработкі геаметрыя проста называецца раскладам. Кожны наступны этап, які запускаецца пасля змены, зазвычай называецца рефлоу, а дзеякія команды для таго ж значэння вжываюць неформальны термін relayout:
Layout
↓
Initial calculation
Reflow / ReLayout
↓
Subsequent layout calculation
У рэште гіда вжываецца термін рефлоу, адколькі самэ гэта слова можна знайсці ў большасці дыскусый пра выдатнасць і інструментах.
Што спрычынае рефлоу
Пачнім з касеты, якая мае фіксаваную шыроў:
.box {
width: 200px;
}
Тепер скрыпт змінюе гэту шыроў пад час выконання:
box.style.width = "500px";
Гэтае прызначэнне выклікае низ пытанняў, на якія браузер должен адпаведаць, перш чым зможа намалёваць наступны кадр:
The box changed width.
What else is affected?
Does its parent change?
Do neighboring elements move?
Does the text wrap differently?
Does the height change?
Does the entire layout need recalculation?
Таму частына або весь старонік можа патрабаваць новаг этапу раскладу, пасля чаго будуць запускацца і наступныя етапы:
Change width
↓
Style recalculation
↓
Layout / Reflow
↓
Paint
↓
Composite
Атрыбуты, якія вплываюць на геаметрыю
Будзь-яяе якостнае атрыбут, якае вплывае на размер чыста положэнне, можа спрычынаць перакалкаванне лейауту. Найбольш падозрыяваныя з іх:
width
height
margin
padding
top
left
right
bottom
font-size
Змена аднаго з іх можа перасунуць чыста зменіць размер самага элемента, а таксама, можліва, всього, што знаходзится ў яго навакол. Напрыклад, обе прыказы нижэй можу змусіць браузер перасчытаць лейаут:
element.style.width = "500px";
element.style.marginLeft = "100px";
font-size таксама патрабуецца ў гэтым списку, таму што змена размеру тексту вплывае на высоту рэчкі чыста на спосаб её адформатавання, што зменяе высоту блока, які яго размешчае, а з тым і положэнне всього, што находзится пасля яго.
Чаму перакалкаванне лейауту ўскладненая задача
Разглядзім типовую структуру стороніцы з калькамі регіонаў чыста вярстаным контэнтам:
Page
│
├── Header
├── Navigation
├── Sidebar
├── Main Content
│ ├── Card
│ ├── Card
│ ├── Card
│ └── Table
└── Footer
Якщо элемент, які знаходзится падыней, стане вышэй, кожны карточкі, таблыця чыста футер пад яму можу запатрабаваць новыя координаты. Одна-едзінстая змена геаметрыі можа распрасціцца на вялікую частку структуры:
One Geometry Change
↓
Layout Recalculation
↓
Many Elements Recalculated
↓
Paint
↓
Composite
Такая розгалужэнасць прычыніць высокія витраты на форматаванне, бо ўся гэта праця прабывае занову пад час анімазіі чыраўкі.
Этап 6: прадрукаванне
Калі ўсе тры аспекты будуць усталяваны, браузер можа пачаць ствараць пікселі:
What to display
+
Where to display it
+
How it should look
Прадрукаванне ператварае розташоўаныя элементы на операціі адрасавання і, востатку, на пікселі. У складзе прадрукаванага кантэнту ёсць:
- тэкст
- кольоры і фоны
- грані
- цені
- зображэння
- будзь-якія іншыя відразлівыя дэкоратывы
Layout
↓
Paint
↓
Pixels
MDN апісвае прадрукаванне як этап, пры яком элементы з форматавання ператвараюцца на рэальныя пікселі на экране.
Паўторна прадрукаванне: новыя пікселі, тая ж геаметрыя
Паўторна прадрукаванне неабходна, калі элемент выглядае інакша, але займае абоўсумова той самы прастор. Класычным прыкладам є змена кольору тэксту:
color: red;
Новы калер не вплывае ні на што з наступнага:
Width
Height
Position
Layout relationships
Таму браузер можа абсалютна прыняць менш довгі шлях:
Style Recalculation
↓
Paint / Repaint
↓
Composite
Reflow протык repaint парадульна
Гэта разліка ёсць сэрца большасці парадоў пра выкананне, таму варта точна апісаць кожную з сторон.
Reflow перысчыляе геаметрыю
Reflow значыць, што размер або пазіцыя прынеймна адного элемента трэба зноў вырахаваць. Змена шыроці — стандартны прыклад:
element.style.width = "500px";
Потым выканаецца цэлы ланцуг стадзій:
Change
↓
Style
↓
Layout / Reflow
↓
Paint
↓
Composite
Repaint толькі перамальоввае выгляд
Repaint значыць, што элемент выглядае інакш, але геаметрыю не трэба перысчыляць. Дастатнек адзін раз задаць калер, каб гэта сталася:
element.style.color = "red";
Layout не ўключаецца ў ланцуг:
Change
↓
Style
↓
Paint / Repaint
↓
Composite
Кожны з ягох скарацаны да аднай лініі:
RELayout / Reflow
→ Geometry changes
Repaint
→ Visual appearance changes
Кнопка, яка змінюе шырыню або калераць
Уявіце простую кнопку-заклекчанне да дзеяння:
┌─────────────────────┐
│ Buy Now │
└─────────────────────┘
Падумайце, што ўсё яе шырыню зменяюць з першага значэння на другое:
width: 200px;
width: 400px;
Кнопка тады займае удвое большы прастор у горизонтальнам напрамку, што можа адвярнуць суседзяючы элементы або спрычыніць перарабатка рядка. Це змяна геаметрыі, таму браузер пераранжавае элементы і пасля таго перамальоввае ўсё:
Width changes
↓
Geometry changes
↓
Reflow
↓
Repaint
Тады падумайце, што зменяецца толькі калераць фону:
background-color: blue;
Кнопка застаецца з тым самым розмерам і пазіцыяй, а зменяюцься толькі яе пікселі:
Color changes
↓
Geometry unchanged
↓
Repaint
Связь ўсёга ёсць однакім напрамкам
Калі змянюецца макет, элементы апошней падаюць у новыя месца, а для новых месцаў патрэбны новыя пікселі:
Layout changes
↓
Browser needs new pixels
↓
Paint
Корача кажучы, пасля пераранжавання элементаў зазвычай выконваецца ўсуненне і перамальовванне:
Reflow
↓
Usually followed by
↓
Repaint
Такое правила не дзеяе. Перазрасаванне можа адбыцца сама по сабе без жадных дзействаў з макетам:
Repaint
↓
Does NOT necessarily require
↓
Reflow
Этап 7: складанне слоёў у кадр
Савэцкія двыжакі не завжды раскрашваюць всю сторанку як адну плоскую картынку. Яны можа раздзеліць контэнт на адзінаковыя слоі і скласаваць іх у фінальным складанневым этапе:
Layer 1
+
Layer 2
+
Layer 3
↓
Composite
↓
Final Frame
Напрыклад, сторанка можа мець слой фону, карточку на сваім слае і анімаваны элемент на трэцьям слое:
┌──────────────────────┐
│ Background Layer │
│ │
│ ┌──────────────┐ │
│ │ Card Layer │ │
│ └──────────────┘ │
│ │
│ ┌──────────────┐ │
│ │ Animation │ │
│ └──────────────┘ │
└──────────────────────┘
Складальнік складае гэтыя слоі, каб стварыць кожны кадр. Дзеяння дазейснічаюцыя над адзінаковымі элементамі могу быть пераказаны на ўласны слой, а ў падходячых случаях прыгледачы пераказваюць задачу складання GPU. Тады змяны, якія толькі перамешчаюць або сумашчуюць існуючы слой, можна застосавіць без перарасавання яго контэнту.
Чаму transform ёсць стандартны спосаб для руху
Ёсць эфект наведення, які перамешчае ящык праз анімаванне параметра left, прычымляючы з нуля:
.box {
left: 0;
}
і заканчваецца на 100 пікселей правей:
.box:hover {
left: 100px;
}
Пакалькі параметр left ўскладнюе пазычэнне положэння элемента ў лейауте, кожны крок анімазіі выклікае перыявленне лейауту і перамальовку. Той самы візуальны рух можна выражыць за дапамою трансфармазій:
.box {
transform: translateX(0);
}
.box:hover {
transform: translateX(100px);
}
Трансфармазія перамешчае вучыну прамальованы элемент без змены яго лейаутавага контэйнера, таму браузер часта можа обрабатваць усю анімазію ў композітары, без перыявлення лейауту чыста перамальовкі кожнага кадру. Параметр opacity мае падобныя характэрыстыкі і ўжоўчай выбіраецца для эфекта плавнага згасання.
Спрыяйце гэтаму як сильнай стандартной практыцы, а не як закону. Тое, чы реальна трансфармазія застаецца ў композітары, залежыць ад элемента, іншых стыляў, якія ўжо застосаваны да яго, способу распадзелу шароў і конкрэтнага двіжка.
Калькі ля якіх стадій насправды запускаюцца
Для большайшай часткі апдэйтаў стылю робота распадаецца па аднай з двух гілакоў пасля перыякання стылю:
Change
↓
Recalculate Style
↓
┌───────┴───────┐
↓ ↓
Layout No Layout
↓ │
Paint │
↓ ↓
└───────┬───────┘
↓
Composite
↓
Screen
Чым менш каштовных стадій задае часты апдэат, тым лёгкая ўтримаць плавнае адражэнне. MDN описвае той самы процес: перыякання стылю, пасля чаго выконваецца распалажэнне, праз мальваванне і, як толькі гэта можліва, складанне. Змены ў transform або opacity на шары, якія ўжо складаны, могу прыняць шлях нават без стадіі мальвавання, якая є самай дешавай з усіх.
Бюджет кадра: апошней 16,67 мс
Большасць дыскрэйнаў апдзейнаваюцца прыбліжна 60 разоў за секунду, што залічвае фіксаваны час для кожнага кадра:
1 second
÷
60 frames
≈
16.67ms per frame
Іншымі словамі, каб падтрымаць 60 FPS, браузер мае прыбліжна столькі часу на кожны кадр:
16.67ms
Этот бюджет кадра выкарыстоўваецца для всіх задач, якія павінны выконвацца пры адобразэнні кадра: ваш JavaScript, вычысленне стылю, парадакт элементаў, аплёвка кольору і власныя функцыі браузера. Калі загальная колькасць ресурсаў перакрое гэты бюджет, кадр не будзе адобразіцца, і корыстнік пабачыць перашкоды ў роботе:
16.67ms
↓
Exceeded
↓
Frame missed
↓
Jank
Этот эфект найболей зрозумілы ў ситуаціях, калі кадры ствараюцца пастойчыя:
- перемещэнне стрэлкі пры наведэнні
- анімацыі
- функцыя «ператаскання і падвеска»
- змена размеру вікна або панелі
- панелі керування, якія аднойчы апдэйтуюць многа значэнняў
MDN таксама падчеркнуў, што вычысленне стылю, парадакт элементаў і аплёвка кольору павінны ўсе спадзявацца ў межах бюджету кадра, каб анімацыя выглядала плавна.
Проблемы з парадактом элементаў: чытанне, якое вымагае сінхроннага парадакту
Ўсілай распашчвання бюджету кадра часта выглядае безнэшкодна ў кодзе. У прыкладзе нижэй задаёцца шырына, чытаецца розмер, задаёцца высота і зноў чытаецца:
element.style.width = "500px";
console.log(element.offsetWidth);
element.style.height = "500px";
console.log(element.offsetHeight);
Формат, які ўтвараецца, — цэлыя змены між запісамі та чытаннямі:
Write
↓
Read layout
↓
Write
↓
Read layout
Зазвычай браузер відкладае форматаванне паказвальнай сцэны да моменту атрыбутавання наступнага кадру, таму калькіляцыі стылю можна адрабатваць за адну процэсуру. Аднак такія властывасці, як offsetWidth і offsetHeight, павінны вяртаць тэкучыя значэння. Чытанне іх адразу пасля запісу змушвае двойчык синхронна, негайна атрыбутаваць усе запланаваны стыль і форматавання. Якщо робіць така дзеяння раз за разам, частаўка ў цікле над многама элементамі, то вытвараецца занадта частае форматаванне: многія повныя процэсы форматавання, калі бы хватіла толькі адна.
Рашэння — групаваць операцыі так, каб усе чытання вядзаліся першыя, а ўсе запісы — пасля:
Bad:
Write
Read
Write
Read
Write
Read
Better:
Read
Read
Read
Write
Write
Write
Спосаб пераструктуравання коду залежыць ад прыемлена, але прынцып завжды той самы: не заставляйте браузер перасчыляць лейаут частае, чым это неабходна. У блогу ёсць болей дакладны аналіз проблемы перасчылення лейауту і колекцый жывага DOM, якщо хочаце больш прыкладоў прыводзячых да праспешнага перасчылення.
Практычныя методы для эфективнейшага атрыбутавання
Анімаванне параметраў transform і opacity
У замест на перасунуць элемент за дапамою атрыбута лейауту, напрыклад:
left: 100px;
выберыце параметр transform, які падходзіць да дизайну:
transform: translateX(100px);
Для згасання элемента і яго павтарнага праказвання, зміняйце межы між гэтымі двума значэннямі:
opacity: 0;
opacity: 1;
зазвычай яе выбіраюць замест на анімаванне атрыбутаў, якія вплываюць на лейаут.
Мінімізавайце змены ў DOM
Кожная мутацыя DOM можа запланаваць большую колькасць задач для прыгледчыка. Дадзенне вузлаў аднаго за іншым у такой последовасці:
element.appendChild(...);
element.appendChild(...);
element.appendChild(...);
часта краща заменіць на стварэнне новага кантэнту па-іншым спосабам (напрыклад, за дапамою DocumentFragment) і ўведэнне яго аднойчы. Чым больш і складнейшы DOM, тым вышэй косць кожной непатрэбнай змены.
Апдэйты групава, а не па черзе
Код, які змінюе апдэйты з роботай над макетам, у канцыкаві дае такую последовасць:
Update
↓
Layout
↓
Update
↓
Layout
↓
Update
↓
Layout
Мета — даць прыгледчыку групу змян, якія ён можа обрабаваць разам:
Update
Update
Update
↓
Browser processes the changes
Для анімацый і іншай візуальной роботы высокай частоты requestAnimationFrame() плануе вашы апдэйты так, каб яны выконваліся непразьле да таго, калі прыгледчык атрыбуе наступны кадр, чым яны залишаюцца сувязаныя з цыклам атрыбавання, а не суперчаць яму.
Не анімавайце настройкі змесцовання
Настройкі, які зменяють геаметры, не паджуюць для викорыстання ў тых элементах, які працуюць кожнай кадр:
width
height
margin
padding
top
left
right
bottom
font-size
Кожна з іх можа спрычыніць пераскладку. Як толькі візуальны рэзультат дазваляе, анімавайце замест таго гэтыя настройкі:
transform
opacity
Звярніце месца для адпраўк
Таг адпраўкы без парадактов не дае браузеру інфармацыі пра тое, сколькі месца трэба залишыць:
<img src="image.jpg">
Калі файл прыбывае і становіцца вядомым яго рэальны размер, атрыбуты наваколле змінююцца і зноў адбываецца пераскладка. Адзначэнне внутранняга размеру заздалегідь запобiegае гэтаму:
<img
src="image.jpg"
width="800"
height="600"
alt="Example"
/>
У CSS параметр aspect-ratio дае той самы эфект для адпраўк, якія прыстосаваны да разных размераў экрана. У будзь-якім случае браузер можа звярнуць правільныя параметры першым, пры чым адпраўка не будзе змінюваць свой візуальны выгляд.
Звярніце меры прычымоўна да оптымазаціі
Не кожна перапісваўка або пасэж рэанарабавання є проблемай, якую трэба рашыць; двыжакі сильна оптымізаваны і швядка виконваюць большасць такой роботы. Акцэнтавайце своі зусілі на доказах за дапамой простаг цыклу:
Performance Problem
↓
Measure
↓
Find Bottleneck
↓
Optimize
↓
Measure Again
Панель Performance у Chrome DevTools фіксуе часовую шкалу, якая паказвае:
- Выконанне JavaScript
- Перыяканне стылю
- Рэанарабавання лейауту
- Пісваўка экрана
- Работу з композіцыяй
- Дзейнікі з довгым часам выконання
- Час на адзін кадр
Шукайце прычыну спаду продуктывнасці, якую паказвае аналіз, а не код, які проста выглядае складным пад час чытання.
Усі етапы ў адной картцы
Якщо рассмотрэць усё ад початку да канца, парадок з выхадным матэрыялам да экрана выглядае так:
HTML
│
↓
Parse HTML
│
↓
DOM
│
│
CSS ──→ Parse CSS ──> CSSOM
│
↓
DOM + CSSOM
│
↓
Render Tree
│
↓
Style Calculation
│
↓
Layout / Reflow
│
↓
Paint / Repaint
│
↓
Composite
│
↓
Pixels on Screen
А калі пасля першага атрыбутавання ўсё змінюецца, ключовы момент прыняцтва рашэння — чы рушае геаметрыя:
CSS / DOM Change
↓
Style Recalculation
↓
Does geometry change?
│
┌──┴──┐
YES NO
│ │
↓ ↓
Layout Paint
│ │
└──┬───┘
↓
Composite
↓
Screen
Галоўныя выводы
Тры наступныя стыслае падзеўкі апісваюць галоўнае, што мае значэнне. Прызначэнне паветранага прастору — это дарогі варыянт:
RELayout / Reflow
↓
Changes geometry
↓
Width / Height / Position / Layout
↓
Usually leads to Paint
Перамальваванне — это дышэўнейшы варыянт:
Repaint
↓
Changes appearance
↓
Color / Background / Shadow / etc.
↓
Doesn't necessarily require Layout
А ў разе анімацыі выбор атрыбута значна вплывае на выкладкі:
Layout properties
↓
Potentially expensive
transform + opacity
↓
Often better for smooth animations
Вам не трэба знать внутрошняе строенне кожнага двыжка, але вы должны можаць разумець загальную схему ўзробкі:
HTML
↓
DOM
CSS
↓
CSSOM
DOM + CSSOM
↓
Render Tree
↓
Style
↓
Layout
↓
Paint
↓
Composite
↓
Pixels
З урахоўваннем гэтай моделі:
- Змены геаметрыі, такія як
width, спрычыняюць перзначэнне паветранага прастору, а потым перамальваванне; змены візуальных настройкаў, такія якcolor, зазвычай выкалікаюць толькі перамальваванне. transformіopacityчаста дазволяюць прыбегнуць да анімацыі без перзначэння паветранага прастору і перамальвавання.- Адгрупаванне запісаў DOM з чытанням ўзробкі спрычыняе працяжны процес ўзробкі; кращэ чытаць раней, чым запісваць.
Браузер завжды выканае рэальную работу, каб ператворыць код у пікселі. Мета не ў тым, каб усунуць гэтую работу, а ў тым, каб не прасіць браузера выканаць больш, чым на самай працэ падазроўанай сторонкі трэба.