Noche. Un golpe en la puerta. Abierto. Hay dos. "¿Crees en el bucle de eventos, nuestra principal cadena de navegadores?" Tomar un respiro. Cierre la puerta. Acuéstate para llenar. Aún quedan 4 horas antes del inicio de la jornada laboral. Y ya hay un evento de bucles, layouts y otras alegrías ...
En la primera parte, hablamos sobre la primera carga y el trabajo con recursos. Hoy hablaré sobre la segunda parte de la optimización del rendimiento de front-end. Acerca de lo que le sucede a nuestra página cuando se carga, en qué tiempo de CPU se gasta y qué hacer con ella. Palabras clave: bucle de eventos, pintura \ repintado, diseño \ reflujo, compuesto.
La corbata. Preguntas de autoevaluación
Si desea comenzar a absorber el contenido del artículo de inmediato, omita esta sección.
El bucle de eventos es popular no solo en el trabajo diario, sino también en las entrevistas. Y averigüe dónde es más popular. Hay tres preguntas que debe hacerse para comprobar si comprende este mecanismo de navegador. Dos de ellos son habituales de las entrevistas, pero el tercero muestra una comprensión del ciclo de eventos para su práctica. Son bastante simples, pero se organizarán en orden ascendente de dificultad:
"1" ? ?
function loop() { Promise.resolve().then(loop); } setTimeout(() => {console.log(1)}, 0); loop();
, ,
cursor: pointer
:hover
CSS ,:hover
background-color
c . :
while (true);
: ? ? ?
height 0 auto? c JS / CSS. , , stackoverflow . event loop ,
height = auto
JS.
:
,
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, ..)
- , , ,
transform
will-change
.transform
composition
,will-change
composition
. .
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 :