¿Qué sucede si nos manipular el árbol DOM en requestAnimationFrame?

0

Pregunta

Mi comprensión es que, siempre hay una cierta manipulación del árbol DOM como la inserción de un elemento de DOM desencadenaría un reflujo y lo más probable es seguido por un repintado. Por favor me corrija si estoy equivocado. Citando el MDN Web Docs,

La ventana.requestAnimationFrame() método indica al navegador que desea realizar una animación y pide que el navegador llama a una función especificada para actualizar una animación antes de la próxima repintar

el requestAnimationFrame (un.k.una. aAF) callback es llamado justo antes de que el navegador está a punto de volver a pintar. Así que ¿significa esto que si nos arreglan para hacer una manipulación del árbol DOM en el interior de este rAF (edit: y también la cola de otro rAF en la final), que provoca un reflujo de cada vez y por lo tanto un repintado, estaríamos atrapados en un bucle infinito sin procesamiento realmente nada en la pantalla.

O es el caso que, una vez que el explorador había decidido hacer un repintado, se pega con él y de aplicar las actualizaciones que sucedió en la RAF de devolución de llamada en el siguiente repintado?

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

Mejor respuesta

1

siempre que hay una cierta manipulación del árbol DOM como la inserción de un elemento de DOM desencadenaría un reflujo y lo más probable es seguido por un repintado

La pintura de acción se produce de forma asíncrona, por lo que "gatillo" debe ser entendido de esa manera. En primer lugar, el código JavaScript se termine antes de que realmente suceda.

si nos arreglan para hacer una manipulación del árbol DOM en el interior de este rAF (edit: y también la cola de otro rAF en la final), que provoca un reflujo de cada vez y por lo tanto un repintado, estaríamos atrapados en un bucle infinito sin procesamiento realmente nada en la pantalla.

Las necesidades para repintar se acumulan y no de forma sincrónica cumplido. En primer lugar, el código tiene que completar hasta que la llamada pila está vacía. Así que no hay ningún bucle infinito aquí.

O es el caso que, una vez que el explorador había decidido hacer un repintado, se pega con él y de aplicar las actualizaciones que sucedió en la RAF de devolución de llamada en el siguiente repintado?

Sí. Cuando la RAF callback es llamado, que el código que se obtiene de una última oportunidad para hacer las actualizaciones a la catedral, que se puede acumular más de las necesidades para la pintura. Si en ese devolución de llamada también se registra otro de devolución de llamada en la RAF, no se ejecutará en ese momento, pero más tarde: en la siguiente vez que el navegador se encargará de preparar su repintar la tarea, así que no es la actual.

Ejemplo simplificado

Digamos que usted tiene este código:

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);
}

Cuando se ejecuta, se obtiene la siguiente secuencia:

  1. update está registrado como de devolución de llamada
  2. El fondo de cambiar los horarios de una necesidad de volver a pintar
  3. La pila de llamadas se queda vacío
  4. El navegador se inicia su repintar trabajo, pero toma en cuenta que es un registro de devolución de llamada. Así se elimina este registro (ya que se ejecuta sólo una vez) y se ejecuta update antes de hacer nada.
  5. El cambio de ancho de los horarios de una necesidad de volver a pintar. La lista de cambios incluye ahora en el fondo de cambio y este cambio de ancho y cualquier efecto en cascada que se ha calculado. (¿Cómo se representa es explorador dependiente)
  6. El update la función está registrada como devolución de llamada de nuevo.
  7. El navegador ahora comprueba lo que tiene que hacer como parte de este repaint de trabajo, y realiza todo lo que se necesita para visualizar los efectos de los antecedentes y la anchura de los cambios.
  8. La pintura se termina el trabajo. Todo lo que queda es el domicilio update de devolución de llamada.
  9. Cuando el navegador realiza su siguiente ciclo de pintura, de empezar de nuevo desde el paso 4, pero ahora no está en la cola de fondo-cambiar más. Para el resto será el mismo proceso.
2021-11-21 12:57:10

"4. El navegador se inicia su presentación/repintar trabajo," que es bastante confusa formulación, creo que decir que "el navegador se inicia la actualización de la representación" sería un poco menos confuso. El diseño y la repintar están separados, puede muy bien la fuerza de un diseño de forma sincrónica de usuario código de la tierra, no se puede forzar una actualización, que será siempre el último paso de la representación de los pasos. También, creo que las respuestas a los puntos primero sería mucho más sencillo recordando desde el principio que raf(()=>raf(fn2)) programar fn2 para disparar en el siguiente cuadro. De lo contrario, esta respuesta es correcta.
Kaiido

@Kaiido, gracias por tu comentario. "puede muy bien la fuerza de un diseño de forma sincrónica de usuario código de la tierra": ¿te refieres a un usuario perceptible cambio en el diseño? puede usted dar un ejemplo de código para que?
trincot

De cualquier manera, he quitado la referencia a la presentación.
trincot

gist.github.com/paulirish/5d52fb081b3570c81e3a Aquí está una lista de qué es lo que desencadena el diseño, y sí, es "el usuario "perceptible": stackoverflow.com/questions/55134528/...
Kaiido

Bien, Kaiido!
trincot

En otros idiomas

Esta página está en otros idiomas

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