Otimizando o desempenho do front-end. Parte 2. Loop de evento, layout, pintura, composto

Noite. Uma batida na porta. Abrir. Existem dois em pé. "Você acredita no loop de eventos, nossa principal rede de navegadores?" Respire. Feche a porta. Deite-se para encher. Faltam ainda 4 horas para o início da jornada de trabalho. E já existe um evento de loops, layouts e outras alegrias ...



Na primeira parte, falamos sobre primeiro carregar e trabalhar com recursos. Hoje vou falar sobre a segunda parte da otimização do desempenho do front-end. Sobre o que acontece com nossa página quando ela é carregada, quanto tempo de CPU é gasto e o que fazer com ele. Palavras-chave: loop de evento, pintura \ repintar, layout \ refluxo, composto.





A gravata. Perguntas de autoteste



Se você quiser começar a absorver o conteúdo do artigo imediatamente, pule esta seção.



O loop de eventos é popular não apenas no trabalho diário, mas também em entrevistas. E descubra onde é mais popular. Há três perguntas a se fazer para verificar se você entende esse mecanismo do navegador. Dois deles frequentam entrevistas regulares, mas o terceiro mostra uma compreensão do ciclo de eventos de sua prática. Eles são bastante simples, mas serão organizados em ordem crescente de dificuldade:



  1. "1" ? ?



    function loop() {
    Promise.resolve().then(loop);   
    }
    setTimeout(() => {console.log(1)}, 0);
    loop();


  2. , , cursor: pointer :hover CSS , :hover background-color c . :



    while (true);


    : ? ? ?



  3. 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 ?

:



  1. <script>
  2. : setTimeout, setInterval, requestIdleCallback
  3. XmlHttpRequest, fetch ..
  4. API: click, mousedown, input, blur, visibilitychange, message , . ( , - ..).
  5. . , JS
  6. , : DOMMutationObserver, IntersectionObserver
  7. RequestAnimationFrame
  8. - ? :)


WebAPI ( API). :



  1. setTimeout(function a(){}, 100)
  2. WebAPI 100
  3. 100, WebAPI function a() (TaskQueue)
  4. 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 , .



. :



  1. :
  2. : , , ..


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 . :



  1. raf : DOMHighResTimeStamp — . perfomance.now,



  2. setTimeout, raf (id), raf cancelAnimationFrame.



  3. , — . Raf



  4. JS , , , requestAnimationFrame



  5. , ? :



    const checkRequestAnimationDiff = () => {
    let prev;
    function call() {
        requestAnimationFrame((timestamp) => {
            if (prev) {
                console.log(timestamp - prev); //     16.6 ,  60FPS
            }
            prev = timestamp;
            call();
        });
    }
    call();
    }
    checkRequestAnimationDiff();


    , ( hh.ru):





  6. () 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 :



  1. (offsetWidth, offsetLeft, getBoundingClientRect, ..)
  2. , , , 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:



  1. DOM
  2. force layout


Paint





, color, background .. :





, , . .



, , — Composition.



Composition





, - GPU. CSS , transform.



: .



: transform: translate . transform: translateZ(0) " ", .



GPU. .





transform . :



  1. transform layout ,
  2. "" , left, right, top, bottom


, transform , . .



?



( ) — layout. layout hh.ru. DOM, , 13-20 . .



:





Layout, , ..





layout paint, transform .



, :



  1. CSS. JS
  2. transform “”
  3. will-change — , "" . — , . , .
  4. DOM
  5. requestAnimationFrame
  6. \ . , layout.
  7. , . , , .




Runtime , . :



  1. ,


event loop :






All Articles