Mengoptimalkan kinerja frontend. Bagian 2. Lingkaran peristiwa, tata letak, cat, komposit

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