Čo sa stane, ak budeme manipulovať DOM v requestAnimationFrame?

0

Otázka

Moje pochopenie je, vždy, keď je nejaký DOM manipulácia ako vloženie DOM prvok by vyvolalo reflow a s najväčšou pravdepodobnosťou nasledovať prekresliť. Prosím, opravte ma ak sa mýlim. Uveďte MDN Webové Dokumenty,

Na okno.requestAnimationFrame() metóda rozpráva prehliadač, ktorý si želáte vykonať animácie a žiadosti, ktoré prehliadač hovory zadaná funkcia na aktualizáciu animáciu pred ďalším prekresliť

na requestAnimationFrame (a.k.a. aAF) žiadosť o spätný hovor, sa nazýva tesne pred prehliadač je o prekresliť. Takže znamená to, že ak sa nám nejako podarí urobiť DOM manipulácia vnútri tejto rAF (edit: a tiež frontu iného rAF na konci), ktorý spúšťa reflow všetko, a teda prekresliť, by sme byť uviazol v nekonečnej slučke bez vlastne vykresľovanie čokoľvek na obrazovke.

Alebo je to v prípade, že raz prehliadač rozhodol urobiť prekresliť, to bude držať s ním a uplatňovať všetky aktualizácie, ktoré sa stalo v RAF žiadosť o spätný hovor v ďalšom prekresliť?

dom javascript reflow repaint
2021-11-21 07:17:28
1

Najlepšiu odpoveď

1

vždy, keď je nejaký DOM manipulácia ako vloženie DOM prvok by vyvolalo reflow a s najväčšou pravdepodobnosťou nasledovať prekresliť

Maľovanie akcia sa vyskytuje asynchrónne, tak "trigger" by sa mal chápať týmto spôsobom. Prvý kód JavaScript sa dokončiť skôr, než sa tak skutočne stane.

ak sa nám nejako podarí urobiť DOM manipulácia vnútri tejto rAF (edit: a tiež frontu iného rAF na konci), ktorý spúšťa reflow všetko, a teda prekresliť, by sme byť uviazol v nekonečnej slučke bez vlastne vykresľovanie čokoľvek na obrazovke.

Potreby pre prekresliť sa hromadia a nie sú synchrónne splnené. Prvý kód musí dokončiť, kým hovor zásobník je prázdny. Takže nie je nekonečné slučky tu.

Alebo je to v prípade, že raz prehliadač rozhodol urobiť prekresliť, to bude držať s ním a uplatňovať všetky aktualizácie, ktoré sa stalo v RAF žiadosť o spätný hovor v ďalšom prekresliť?

Áno. Keď RAF spätný hovor sa nazýva kódu, ktorý dostane posledná šanca, aby sa aktualizácie na DOM, ktorý môže hromadiť ďalšie potrieb pre maľovanie. V prípade, že v žiadosti o hovor môžete tiež zaregistrovať ďalší hovor na RAF, nevykoná v tom čase, ale neskôr: na budúci čas, aby prehliadač pripraví prekresliť jeho úlohou -- tak nie je aktuálny.

Zjednodušený príklad

Povedzme, že máte tento kód:

requestAnimationFrame(update);

myElement.style.backgroundColor = "silver"; // This queues a need for repaint

function update() {
    // This queues a need for repaint
    myElement.style.width = Math.floor(Math.random() * 100) + "px";
    requestAnimationFrame(update);
}

Keď sa to spustí, dostaneme nasledovnú postupnosť:

  1. update je registrovaný ako spätný hovor
  2. Na pozadí zmeniť plány potrebné pre prelakovanie
  3. Na callstack stáva prázdne
  4. Prehliadač začína jeho prekresliť prácu, ale berie do úvahy, že je registrovaná spät. hovor. Takže sa odstráni táto registrácia (pretože to by mala spustený iba raz) a spustí update predtým, než robiť niečo iné.
  5. Šírka zmeniť plány potrebné pre prelakovanie. Zoznam zmien teraz zahŕňa pozadie zmeniť, a to šírka zmeniť a všetky kaskádový efekt, ktorý bol vypočítaný. (Ako to je zastúpený je závislé od prehliadača)
  6. Na update funkcia je zapísaná napríklad spätný hovor znova.
  7. Prehliadač teraz kontroly, čo potrebuje urobiť, ako súčasť tejto prekresliť prácu a plní všetko, čo je potrebné na sprehľadnenie účinky pozadí a šírka zmeny.
  8. Farba práca končí. Všetko, čo je vľavo je registrovaná update žiadosť o spätný hovor.
  9. A keď sa v prehliadači vykonáva jeho ďalšie farby cyklu, sme začnite znovu od kroku 4, ale teraz nie je vo fronte na pozadí-zmena, nič viac. Pre zvyšok bude to rovnaký proces.
2021-11-21 12:57:10

"4. Prehliadač začína jeho rozloženie/prekresliť prácu," že je to dosť mätúce príprava, myslím, že povedal: "prehliadač spustí aktualizáciu vykresľovanie" by byť trochu menej mätúce. Rozloženie a prekresliť sú oddelené, môžete veľmi dobre sila rozloženie synchrónne od užívateľa-pozemky kód, nedá sa vynútiť prekresliť, ktorý bude vždy posledný krok vykresľovanie kroky. Tiež som pocit, že odpovede na prvé body by to oveľa jednoduchšie, tým pripomínať, z get-ísť, že raf(()=>raf(fn2)) budú plánovať fn2 oheň na ďalší frame. Inak táto odpoveď je správna.
Kaiido

@Kaiido, vďaka za váš komentár. "môžete veľmi dobre sila rozloženie synchrónne od užívateľa-pozemky kód": myslíš, že užívateľ-vnímateľnej zmeny v rozložení? môžete dať kód príklad?
trincot

Akokoľvek, odstránil som odkaz na rozloženie.
trincot

gist.github.com/paulirish/5d52fb081b3570c81e3a Tu je zoznam toho, čo aktivuje rozloženie, a áno, nie je "user-vnímateľné": stackoverflow.com/questions/55134528/...
Kaiido

V Poriadku, Kaiido!
trincot

V iných jazykoch

Táto stránka je v iných jazykoch

Русский
..................................................................................................................
Italiano
..................................................................................................................
Polski
..................................................................................................................
Română
..................................................................................................................
한국어
..................................................................................................................
हिन्दी
..................................................................................................................
Français
..................................................................................................................
Türk
..................................................................................................................
Česk
..................................................................................................................
Português
..................................................................................................................
ไทย
..................................................................................................................
中文
..................................................................................................................
Español
..................................................................................................................