Red de conocimiento del abogados - Preguntas y respuestas jurídicas - ¿Por qué la operación DOM en JavaScript es tan lenta?

¿Por qué la operación DOM en JavaScript es tan lenta?

En el navegador, la implementación de DOM y JS no utiliza la misma "cosa". Por ejemplo, el motor JS con el que estamos más familiarizados en Chrome es V8, y DOM y el renderizado se basan en la biblioteca WebCore. En otras palabras, DOM y JS son dos entidades independientes. Piense en DOM y JavaScript como islas, conectadas por puentes de peaje.

--"JavaScript de alto rendimiento" 1. Agregue elementos de página, método internalHTML?vs?DOM. document.getElementById('test').innerHTML='lt;divgt;testlt;/divgt;';

var?t=document.createElement('div');

t.appendChild(document.createTextNode('test'));

document.getElementById('test').appendChild(t);

Lo anterior utiliza dos métodos respectivamente. un div al elemento con id='test'. Antes, es posible que todo el mundo haya sido adoctrinado con la idea de que el HTML interno es más rápido. ¿Es este realmente el caso?

Eso es cierto, al menos en IE, pero en los nuevos navegadores basados ​​en webkit, usar el método DOM será un poco más rápido. Por lo tanto, qué método utilizar debería seguir siendo algo controvertido. Personalmente me gusta InnerHTML porque es más fácil de usar.

Además, cuando es necesario agregar una gran cantidad de elementos idénticos, cloneNode es un poco más rápido que crear elementos directamente. 2. La forma correcta de acceder a los elementos.

2.1. Atravesar colecciones versus atravesar matrices

Cuando usamos document.getElementsByName, document.getElementsByTagName, document.getElementsByClassName, docuemnt.images, etc. para obtener elementos DOM, obtenemos Es una colección HTML. Esta colección siempre está conectada al documento subyacente. Cada vez que obtenga la información de la colección, se ejecutará una consulta repetidamente. var?divs=document.getElementByTagName('div');

for(var?i=0;ilt;divs.length;i){ document.body.append(document.createElement('div' ))?

}

Si no lo ejecutamos, podemos pensar que el código anterior agregará varios elementos div nuevos a la página, pero de hecho, porque cada vez uno Si se agrega div, divs.length se actualizará (incrementará en uno), por lo que este ciclo nunca se detendrá. La solución es muy simple var?divs=document.getElementByTagName('div');

for(var?i=0,len=divs.length;ilt;len;i){ document.body. append (document.createElement('div'))?

}

Además, la colección HTML no es una matriz. Si necesitamos recorrer esta colección, primero podemos copiar. en una matriz, de modo que cuando lo atraviese nuevamente, será más eficiente.

function?toArray(coll){ for(var?i=0, a=[], len=coll.length; ilt; len; i ){ a[i]=coll[i]?

} return?a;?

}

2.2. Acceder a los atributos del elemento

Al atravesar una colección, el atributo de longitud debe almacenarse en caché fuera del bucle para evitar la lógica. error en 2.1; almacenar colecciones en variables locales también puede mejorar la eficiencia. Además, al acceder a atributos del mismo elemento DOM, almacenar en caché el DOM en una variable local es una mejor opción. //Solo como demostración, por supuesto, no existe tal requisito en situaciones reales

//La peor manera

function?fo1(){

var? nombre=''; for(var?i=0;ilt;document.getElementsByTagName('div');i){

nombre=document.getElementsByTagName('div').nodeName;

name=document.getElementsByTagName('div').nodeType;

}? return?name;?

}

//Mejor manera

función?fo2(){

var?name='';

var?coll=document.getElementsByTagName('div');

for(var?i=0, len=coll.length; ilt; len; i ){ nombre=coll[i].nodeName; nombre=coll[i].nodeType;

}

return?name;

}

//Mejor manera

function?fo3(){ var? var?coll=document.getElementsByTagName('div'); var?ele=null; for(var?i=0, len=coll.length; ilt; len; i ){

el= coll[i]; name=el.nodeName; name=el.nodeType;?

}

} 3. Selector

Delante Se ha mencionado que document.getElementsByName, document.getElementsByTagName, document.getElementsByClassName, docuemnt.images y otros métodos obtienen una colección HTML, lo cual es ineficiente en comparación con querySelector y querySelectorAll, lo que se obtiene es una NodeList, que es un objeto tipo Array no; causar problemas con las colecciones HTML. Además, esta API es más conveniente a la hora de obtener elementos. La única pregunta es si el navegador de destino lo admite. 4. Redibujar y reorganizar

4.1 ¿Cuándo redibujar y reorganizar?

Redibujar no necesariamente conduce a redibujar. Por ejemplo, cambiar el color de un elemento solo provocará un redibujo y, después del redibujo, el navegador debe volver a dibujar las partes afectadas por el redibujo.

Los motivos para la reorganización incluyen:

Agregar o eliminar elementos DOM

Cambios en la posición, el tamaño y el contenido de los elementos

Cambios en el tamaño de la ventana del navegador

Aparece la barra de desplazamiento

Debido a que las operaciones de reordenar y volver a dibujar son muy costosas, el navegador las optimizará poniendo en cola las modificaciones y ejecutándolas en lotes (tengo entendido que el navegador realizará la optimización mediante colas y lotes). ejecución, reduciendo el número de redibujados). Por ejemplo: //Este código no se volverá a dibujar tres veces

var?bodyStyle=document.body.style;

bodyStyle.color='red';

bodyStyle.color='black';

bodyStyle.color='green';

La operación de obtención del diseño hará que la cola se actualice y la optimización del navegador El efecto también se verá afectado. No hay más. Para evitar obtener las siguientes propiedades cuando cambia la información del diseño:

offsetTop, offsetLeft, offsetWidth, offsetHeight

scrollTop, scrollLeft, scrollWidth, scrollHeight;

clientTop; , clientLeft, clientWidth, clientHeight;

getComputedStyle()/currentStyle

4.2 Sugerencias para minimizar la reorganización y el rediseño

Sugerencia: no modificar el diseño nuevamente. Al recibir información, consulte la información de diseño var?computed;

var?tmp='';

var?bodyStyle=document.body.style;

si (document.body.currentStyle){ computed=document.body.currentStyle?

}else{ computed=document.defaultView.getComputedStyle(document.body, '')

}

//malo

bodyStyle.color='rojo';

tmp=computed.backgroundColor;

bodyStyle.color=' verde ';

tmp=computed.backgroundImage;

//bueno

bodyStyle.color='rojo';

bodyStyle color. ='green';

tmp=computed.backgroundColor;

tmp=computed.backgroundImage;

Cuando modifiques varios estilos de un elemento, hazlo a la vez Modifique, no varias veces (aunque las modificaciones múltiples, después de la optimización de los navegadores modernos, solo causarán un reflujo, en los navegadores antiguos, aún causarán múltiples reflujos). Sugerencia: si se puede resolver usando clases CSS, intente no usar estilos en línea.

: el desplazamiento ralentizará la velocidad de respuesta. Evite usarlo cuando trabaje con listas grandes. 5. Delegación de eventos

Cada vez que vinculas un controlador de eventos, hay un precio. Si hay una gran cantidad de elementos que deben vincularse en un momento determinado, intente utilizar la delegación de eventos.

Tres pasos

Determinar el origen del evento

Realizar diferentes operaciones según las diferentes fuentes

Cancelar la propagación y evitar el comportamiento predeterminado (opcional) document.querySelector(' #nav').onclick=función?(e)?{

if?(e.target.nodeName=='A'){

foo();

}else{

foo2()

}

}

Resumen:

Reducir Número de visitas al DOM

Si accede al mismo DOM varias veces, debe utilizar variables locales para almacenar en caché el DOM

Utilice querySelector tanto como sea posible en lugar de utilizar la API para obtener el Colección HTML

Preste atención al redistribución y redibujado

Utilice la delegación de eventos para reducir el número de eventos vinculados

Para obtener más información, puede leer "JavaScript de alto rendimiento "

El contenido anterior de:?cnblogs, www.cnblogs.com/yepbug/p/5427213.html