Nacht. Ein Klopfen an der Tür. Öffnen. Es gibt zwei. "Glauben Sie an die Ereignisschleife, unsere Hauptbrowserkette?" Hol erstmal Luft. Schließe die Tür. Leg dich hin, um dich zu füllen. Es sind noch 4 Stunden bis zum Beginn des Arbeitstages. Und es gibt bereits ein Ereignis von Loops, Layouts und anderer Freude ...
Im ersten Teil haben wir über das erste Laden und Arbeiten mit Ressourcen gesprochen. Heute werde ich über den zweiten Teil der Optimierung der Front-End-Leistung sprechen. Über das, was mit unserer Seite passiert, wenn sie geladen wird, wofür CPU-Zeit aufgewendet wird und was damit zu tun ist. Schlüsselwörter: Ereignisschleife, Paint \ Repaint, Layout \ Reflow, Composite.

Die Krawatte. Fragen zum Selbsttest
Wenn Sie sofort mit dem Aufnehmen von Artikelinhalten beginnen möchten, überspringen Sie diesen Abschnitt.
Event Loop ist nicht nur in der täglichen Arbeit, sondern auch in Interviews beliebt. Und finden Sie heraus, wo es beliebter ist. Sie müssen sich drei Fragen stellen, um zu überprüfen, ob Sie diesen Browsermechanismus verstehen. Zwei von ihnen sind regelmäßige Interviews, aber der dritte zeigt ein Verständnis der Ereignisschleife für ihre Praxis. Sie sind recht einfach, werden aber in aufsteigender Reihenfolge der Schwierigkeitsgrade angeordnet:
"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 :
