Registro de aprendizaje_0902

Redistribuir y redibujar

https://juejin.im/post/6844903734951018504#comment

El proceso de renderizado del navegador.

  1. Analizar html, generar árbol DOM, analizar CSS, generar árbol CSSDOM
  2. Combine el árbol DOM y el árbol CSSDOM para generar un árbol de renderizado
  3. Layout (reflujo): según el árbol de renderizado generado, reflujo (Layout) para obtener la información geométrica (posición, tamaño) del nodo
  4. Pintura: Obtenga los píxeles absolutos del nodo de acuerdo con la información geométrica obtenida del árbol de renderizado y reflujo
  5. Pantalla: envíe los píxeles a la GPU y muéstrelos en la página

Generar árbol de renderizado

El trabajo principal del navegador:

  1. Comience a atravesar cada nodo visible desde el nodo raíz del árbol DOM
  2. Desde cada nodo visible, busque las reglas correspondientes en el árbol CSSDOM y aplíquelas
  3. Según cada nodo visible y su estilo correspondiente, el árbol de renderizado se combina y genera.

Nota: En el primer paso, debemos atravesar los nodos visibles. Los nodos invisibles incluyen:

  • Algunos nodos que no representan nodos, como script, meta, enlace
  • Algunos nodos ocultos por css, como display: none. (Los nodos ocultos por visibilidad y opacidad se seguirán mostrando en el árbol de renderizado, solo los nodos con visualización: ninguno no se mostrará en el árbol de renderizado)

Reflujo (reordenamiento)

Al construir el árbol de renderizado, los nodos DOM visibles y sus estilos correspondientes se combinan, y luego se debe calcular su posición y tamaño exactos en la ventana gráfica del dispositivo (ventana gráfica) .Esta etapa de cálculo es el reflujo.
Para conocer el tamaño y la posición exactos de cada objeto en el sitio web, el navegador atraviesa el nodo raíz del árbol de renderizado. Ejemplos:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <div style="width:50%">
        <div style="width:50%">hello world!</div>
    </div>
</body>
</html>

El primer div establece el tamaño de visualización del nodo al 50% del ancho de la ventana gráfica, y el segundo div establece su tamaño al 50% del nodo principal. En la etapa de reflujo, debe convertirse en valores de píxeles reales de acuerdo con el ancho específico de la ventana gráfica.

Repintar

Al construir el árbol de renderizado y la etapa de reflujo, sabiendo qué nodos son visibles, así como el estilo y la información geométrica específica (posición, tamaño) de los nodos visibles, cada nodo del árbol de renderizado se puede convertir en píxeles reales en la pantalla. Esta etapa se llama volver a dibujar el nodo.

¿Cuándo ocurre el redibujado por reflujo?

La etapa de reflujo calcula principalmente la posición y la información geométrica de los nodos, por lo que cuando el diseño de la página y la información geométrica cambian, se requiere reflujo. Por ejemplo:

  • Agregar o eliminar elementos DOM visibles
  • La posición del elemento cambia
  • El tamaño del elemento cambia (incluidos los márgenes internos y externos, los bordes internos, el tamaño del borde, el ancho y alto, etc.)
  • El contenido cambia (por ejemplo, los cambios de texto o las imágenes se reemplazan por otra imagen de un tamaño diferente)
  • Cuando la página se renderiza por primera vez
  • Cambios en el tamaño de la ventana del navegador

El reflujo definitivamente activará el rediseño y el redibujo no necesariamente lo hará.
Dependiendo del alcance y la extensión del cambio, es necesario recalcular partes grandes o pequeñas del árbol de renderizado. Algunos cambios activarán la reordenación de toda la página, por ejemplo, cuando aparece la barra de desplazamiento o se modifica el nodo raíz.

Mecanismo de optimización del navegador

Dado que cada reordenamiento provocará un consumo computacional adicional, la mayoría de los navegadores optimizarán el proceso de reordenamiento mediante modificaciones en cola y ejecución por lotes. El navegador pondrá la operación de modificación en la cola y vaciará la cola hasta que haya pasado algún tiempo o la operación alcance un umbral. Sin embargo, cuando la operación de obtener la información de diseño, la cola se verá obligada a actualizar, como acceder a las propiedades o utilizar los siguientes métodos:

  • offsetTop 、 offsetLeft 、 offsetWidth 、 offsetHeight
  • scrollTop 、 scrollLeft 、 scrollWidth 、 scrollHeight
  • clientTOP 、 clientLeft 、 clientWidth 、 clientHeight
  • getComputedStyle ()
  • getBoundingClientRect ()

Los atributos anteriores deben acceder a la información de diseño más reciente, por lo que el navegador tiene que borrar la cola y activar un redibujo redistribuido para devolver el valor correcto. Por lo tanto, al modificar el estilo, evite utilizar los atributos anteriores. Si desea utilizarlo, es mejor almacenar el valor en caché.

Reducir el reflujo y redibujar

Minimizar el rediseño y la reorganización

Reducir el número de ocurrencias, fusionar varios cambios en el DOM y el estilo, y luego manejarlos todos a la vez

const el = document.getElementById('test')
el.style.padding = '5px';
el.style.borderLeft = '1px';
el.style.borderRight = '2px';

En el ejemplo, se han modificado tres atributos de estilo, cada uno de los cuales afectará la estructura geométrica del elemento y provocará el reflujo. La mayoría de los navegadores modernos lo han optimizado, por lo que solo se activará un reflujo. Pero si está en el navegador anterior, provocará tres reflujos.

const el = document.getElementById('test')
el.style.cssText += 'border-left: 1px; border-right: 2px; padding: 5px;';

Modificar DOM por lotes

Cuando se necesitan una serie de modificaciones al DOM, se pueden utilizar los siguientes pasos para reducir el número de redibujos redistribuidos:

  1. Saque el elemento del flujo de documentos
  2. Realizar varios cambios en él
  3. Traer elementos de vuelta al documento

El primer y tercer paso pueden causar reflujo, pero después del primer paso, todas las modificaciones al DOM no causarán reflujo, porque ya no está en el árbol de renderizado.

Saque el DOM del flujo de documentos:

  1. Ocultar elementos, aplicar cambios, volver a mostrar
  2. Use DocumentFragment para construir un subárbol fuera del DOM actual y luego cópielo en el documento
  3. Copie el elemento original a otro nodo que esté fuera del documento, luego de modificar el nodo, reemplace el elemento original

Evite activar eventos de diseño síncronos

Al acceder a algunos atributos del elemento, hará que el navegador vacíe a la fuerza la cola y realice un diseño de sincronización forzada.
Ejemplo: quiero asignar el ancho de una matriz de etiquetas p al ancho de otro elemento

function initP() {
    
    
	for(let i=0;i< paragraphs.length;i++) {
    
    
		paragraphs[i].style.width = box.offsetWidth + 'px'	
	}
}

El código anterior lee la propiedad offsetWidth del cuadro cada vez que se ejecuta y luego lo usa para actualizar la propiedad de ancho de la etiqueta p. Como resultado, el navegador debe hacer que la operación de actualización de estilo en el último ciclo surta efecto cada vez que se repita, para responder a la operación de lectura de estilo en este ciclo. Cada ciclo obliga al navegador a actualizar la cola. La optimización es la siguiente:

const width = box.offsetWidth
function initP() {
    
    
	for(let i=0;i< paragraphs.length;i++) {
    
    
		paragraphs[i].style.width = width + 'px'	
	}
}

Para efectos de animación complejos, use el posicionamiento absoluto para sacarlos del flujo del documento

aceleración de hardware css3 (aceleración de GPU)

Supongo que te gusta

Origin blog.csdn.net/vigorZ/article/details/108385614
Recomendado
Clasificación