Introduzcamos brevemente document.Documentfragment
la función de crear un fragmento de documento. Este fragmento existe en la memoria, no en un DOM
nodo real, por lo que insertar sus elementos secundarios no activará el reflujo/redibujo de la página, por lo que puede usarlo para crear múltiples dom
nodos continuamente.
1. Caso
Forma anterior de crear nodos.
let ul = document.getElementsByTagName('ul')[0]
for (let i = 0; i < 100; i++) {
let el = document.createElement('li')
el.innerHTML = i
ul.appendChild(el)
}
Puede echar un vistazo a su curva de rendimiento, porque cada vez que se crea un nodo, activará la 布局(Layout)
operación de reflujo del hilo principal y luego activará 重绘(Piant)
la operación, que se activa 100 veces:
Crear fragmentos de esta manera solo desencadenará una operación de reflujo:
let ul = document.getElementsByTagName('ul')[0]
let frag = document.createDocumentFragment()
for (let i = 0; i < 100; i++) {
let el = document.createElement('li')
el.innerHTML = i
frag.appendChild(el)
}
ul.appendChild(frag)
Análisis de rendimiento:
De la comparación se puede ver que el área violeta Rendering
es la operación de reflujo. Es obvio que la duración de la creación del fragmento es más ventajosa.
2. Ampliar
Amplíe algunas formas de optimizar la eficiencia de renderizado:
- 1. El archivo de estilo debe estar en
head
la etiqueta y el archivo de secuencia de comandos debe estarbody
antes del final para evitar el bloqueo. - 2.
script
El script bloqueará el hilo de renderizado principal, por lo que si no es necesario ejecutar el renderizado sincrónicamente, puede cargarlo después de que se complete el renderizado y usarlo para controlar eldefer
tiempo de carga del script. - 3. Simplifique y optimice
CSS
los selectores para reducir los niveles de anidamiento al mínimo. - 4.
DOM
Se deben colocar varias operaciones de lectura (o varias operaciones de escritura) juntas. No agregue una operación de escritura entre dos operaciones de lectura. - 5. No cambie el estilo uno por uno, cambie el estilo todos a la vez mediante cambios
class
o atributos.csstext
- 6. Intente
transform
usarlo para deformación y desplazamiento, porque esta operación ocurre en el hilo de fusión画(Draw)
y no afectará el hilo de renderizado principal. - 7. Intente utilizar
DOM
páginas web sin conexión, en lugar de realesDOM
, para cambiar los estilos de los elementos. Por ejemplo, opereDocument Fragment
un objeto y luego agregue este objeto una vez completadoDOM
- 8. Primero configure el elemento en
display: none
(requiere 1 reflujo y redibujo), luego realice 100 operaciones en este nodo y finalmente restaure la visualización (requiere 1 reflujo y redibujo). De esta manera, volverá a renderizar dos veces en lugar de potencialmente 100 renderizaciones. - 9. Para elementos
position
con atributos deabsolute
ofixed
, la sobrecarga de reflujo será relativamente pequeña, porque no es necesario considerar su impacto en otros elementos. - 10. Solo cuando sea necesario, establezca el
display
atributo del elemento en visible, porque los elementos invisibles no afectan el reflujo ni el redibujado. Además,visibility: hidden
los elementos solo afectan el redibujado y no afectan el reflujo. - 11. Algunas
js
operaciones de redistribución de página causadas por se puedenwindow.requestAnimationFrame()
ejecutar en animación de cuadros.
!!!Observación:
** reflow
Durante el reflujo, cambiar la posición/tamaño de los elementos y otra información activará una actualización de fusión unificada asíncrona. Por lo tanto, a veces lo cambias primero y width
luego obtienes offsetWidth/clientWidth
el anterior, porque aún no se ha actualizado**