Malam. Ketukan di pintu. Buka. Ada dua posisi. "Apakah Anda percaya pada loop Peristiwa, rantai browser utama kami?" Mengambil napas. Tutup pintu. Berbaring untuk mengisi. Masih ada 4 jam sebelum dimulainya hari kerja. Dan sudah ada acara loop, tata letak, dan kegembiraan lainnya ...
Di bagian pertama, kami berbicara tentang memuat dan bekerja dengan sumber daya. Hari ini saya akan berbicara tentang bagian kedua dari mengoptimalkan kinerja front-end. Tentang apa yang terjadi pada halaman kami saat dimuat, waktu CPU apa yang dihabiskan dan apa yang harus dilakukan dengannya. Kata kunci: event loop, paint \ repaint, layout \ reflow, komposit.

Dasi. Soal tes diri
Jika Anda ingin segera mulai menyerap konten artikel, lewati bagian ini.
Lingkaran acara populer tidak hanya dalam pekerjaan sehari-hari, tetapi juga dalam wawancara. Dan cari tahu mana yang lebih populer. Ada tiga pertanyaan untuk ditanyakan pada diri Anda sendiri untuk diperiksa apakah Anda memahami mekanisme browser ini. Dua di antaranya adalah wawancara tetap, tetapi yang ketiga menunjukkan pemahaman tentang lingkaran acara untuk latihan mereka. Mereka cukup sederhana, tetapi mereka akan diatur dalam urutan kesulitan:
"1" ? ?
function loop() { Promise.resolve().then(loop); } setTimeout(() => {console.log(1)}, 0); loop();
, ,
cursor: pointer:hoverCSS ,:hoverbackground-colorc . :
while (true);
: ? ? ?
height 0 auto? c JS / CSS. , , stackoverflow . event loop ,
height = autoJS.
:

,
Event Loop
. :
while (true) {
if (execQueue.isNotEmpty()) {
execQueue.pop().exec();
}
}
100%. windows. . , , .
. , - , , . :

- .
: , JS ?
:
-
<script> - :
setTimeout,setInterval,requestIdleCallback -
XmlHttpRequest,fetch.. - API:
click,mousedown,input,blur,visibilitychange,message, . ( , - ..). - . , JS
- , :
DOMMutationObserver,IntersectionObserver RequestAnimationFrame- - ? :)
WebAPI ( API). :
-
setTimeout(function a(){}, 100) - WebAPI 100
- 100, WebAPI
function a()(TaskQueue) - Event Loop
JS - DOM. , , - . .
. 2 , JS, CSS . , . JS, (, ..) . Event Loop JS "". render queue:

, . JS , . , SomeJSTasks .
JS 2 :
- TaskQueue — , .. Task
- MicroTaskQueue — MutationObserver. : MicroTask
Event loop . JS , .
. :
- :
- : , , ..
60FPS. . 60FPS, , .
Event Loop , 16.6 ( 60FPS)
TaskQueue
Task, event loop . , .. render queue , .., .
:

3 TaskA, TaskB, TaskC. Event Loop . 4 . Event Loop (Microtask queue render queue) — . EventLoop . 12 . 16 . Render queue , Event Loop . 1 . Event Loop TaskQueue.
Event Loop , . , , , , JS . : JS , , .
:

. 240 , 60FPS 16.6 . , 14 . , event loop render queue, . : , 14 , 15 .
, , :
— , , , .
:
function findJinny() {
debugger;
console.log('It seems you get confused with universe');
}
function goToTheCave() {
findJinny();
}
function becomeAPrince() {
goToTheCave();
}
function findAFriend() {
// ¯\_(ツ)_/¯
}
function startDndGame() {
const friends = [];
while (friends.length < 2) {
friends.push(findAFriend());
}
becomeAPrince();
}
console.log(startDndGame());
. ?
inline , . , . inline. startDndGame, findAFriend. callStack, findAFriend . :

?
. promise, mutationObserver. , TaskQueue.
: , .
, :

fulfilled rejected promise, , .
JS , . , , . : , . . :

4 MicrotaskQueue, , .
— . , MutationObserver — , , mutation observer . , , .
, event loop:

, , RenderQueue ( ).
RenderQueue?
. ( Layout):

:
RequestAnimationFrame (raf)

, - /. - .
DOM . :
raf :
DOMHighResTimeStamp— .perfomance.now,
setTimeout, raf (id), rafcancelAnimationFrame.
, — . Raf
JS , , ,
requestAnimationFrame
, ? :
const checkRequestAnimationDiff = () => { let prev; function call() { requestAnimationFrame((timestamp) => { if (prev) { console.log(timestamp - prev); // 16.6 , 60FPS } prev = timestamp; call(); }); } call(); } checkRequestAnimationDiff();
, ( hh.ru):

() raf , . : https://github.com/whatwg/html/issues/2569#issuecomment-332150901
Style (recalculation)

, - , JS. media queries
a.styles.left = '10px' , CSS , element.classList.add('my-styles-class') CSSOM Render tree.
hh.ru, , Style:

Layout

, , , . DOM , .
layout -. , , Layout update layer tree layout shift, .
— Layout hh.ru .

Layout — -. , style recalculation , Layout :
- (offsetWidth, offsetLeft, getBoundingClientRect, ..)
- , , ,
transformwill-change.transformcomposition,will-changecomposition. .
Layout :
Layout ( raf Style) , , , JS . force layout. , JS Layout.
div1.style.height = "200px"; //
var height1 = div1.clientHeight; //
clientHeight div1 . , JS () : Style ( , ), Layout ( , ). Layout , , div1. , . . Layout Shift. ( , Layout):

layout . , :
div1.style.height = "200px";
var height1 = div1.clientHeight; // <-- layout 1
div2.style.margin = "300px";
var height2 = div2.clientHeight; // <-- layout 2
div1 200px, . layout. . , layout . .
:
div1.style.height = "200px";
div2.style.margin = "300px";
var height1 = div1.clientHeight; // <-- layout 1
var height2 = div2.clientHeight;
layout, .
Layout "" . , chrome devtools -> More tools -> layers:

, event loop , tasks, microtasks force layout:

layout:
- DOM
- force layout
Paint

, color, background .. :

, , . .
, , — Composition.
Composition

, - GPU. CSS , transform.
: .
: transform: translate . transform: translateZ(0) " ", .

transform . :
- transform layout ,
- "" , left, right, top, bottom
, transform , . .
?
( ) — layout. layout hh.ru. DOM, , 13-20 . .
:

Layout, , ..

layout paint, transform .
, :
- CSS. JS
-
transform“” -
will-change— , "" . — , . , . - DOM
-
requestAnimationFrame - \ . , layout.
- , . , , .
Runtime , . :
- ,
event loop :
