Optimierung der Frontend-Leistung. Teil 2. Ereignisschleife, Layout, Farbe, Verbund

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