Hola, somos Arume

Desarrollamos páginas web, aplicaciones para móviles, capas de realidad aumentada y aplicaciones para Facebook. Nos apasiona la informática y somos unos perfeccionistas incurables; por eso en nuestros proyectos utilizamos estándares.

tel. 625 519 694

Mendaña de Neyra, 34, 3º B, 15008, A Coruña

Autenticarse

Registrarse. ¿Has olvidado tu contraseña?

Etiquetas

Saltar las etiquetas

Suscríbete a las RSS

Estás en:

  • Inicio >
  • Blog >
  • jQuery, optimizando para aumentar el rendimiento: el DOM

jQuery, optimizando para aumentar el rendimiento: el DOM

04 Abr 2012 por Luis

Comentarios: 3

jQuery

En artículos anteriores vimos cómo optimizar los selectores en jQuery y otras formas de optimizar jQuery para conseguir un mejor rendimiento de nuestro código. En este artículo trataremos sobre la manipulación del DOM, una acción que es tan costosa que debe tratarse con mucho cuidado.

Recordar que, para la mayoría de proyectos no es necesario rehacer el código pero que siempre podemos tener en cuenta estas pautas en adelante.

Minimizar la manipulación del DOM

La manipulación del DOM (append(), prepend(), after(), ...) es una acción muy costosa ya que requiere del navegador que vuelva a calcular y volver a mostrar el árbol de elementos. Por esta razón, hay que intentar realizar este tipo de acciones lo menos posible. Si, por ejemplo, queremos añadir un array de imágenes a una lista, quizá se nos ocurriría algo así:

var arr = ["imagen_1.jpg", "imagen_2.jpg", "otra_imagen_1.jpg", "otra_imagen_2.jpg", "imagen_3.jpg",
           "otra_imagen_3.jpg", "imagen_4.jpg", "imagen_5.jpg", "imagen_6.jpg", "imagen_7.jpg"];
var list = $("#list");
$.each(arr, function(count, item)
{
	var img = "<li><img src=\"" + item + "\"></li>";
	list.append(img);
});

Sin embargo, hacer tantas inserciones en el DOM es muy lento. Sería mucho mejor acumular primero todo lo que queremos añadir y hacer una sola inserción, de este modo:

var arr = ["imagen_1.jpg", "imagen_2.jpg", "otra_imagen_1.jpg", "otra_imagen_2.jpg", "imagen_3.jpg",
           "otra_imagen_3.jpg", "imagen_4.jpg", "imagen_5.jpg", "imagen_6.jpg", "imagen_7.jpg"];
var tmp = "";
$.each(arr, function(count, item)
{
	var tmp += "<li><img src=\"" + item + "\"></li>";
});
$("#list").append(tmp);

Podemos comparar la diferencia de rendimiento entre una o múltiples inserciones en el DOM en jsPerf.

detach()

Si es necesario realizar muchas tareas sobre un nodo, lo mejor es primero sacarlo del DOM con detach(), hacer todo lo que sea necesario sobre él y luego volver a insertarlo donde estaba. Con eso lo que hacemos es que el navegador trabaje con el elemento en memoria (más rápido) y evitamos que tenga que recalcular todo el árbol de elementos en cada acción.

var table = $("#table");
var parent = table.parent();
table.detach();

// Aquí realizaremos todas las tareas necesarias en la tabla fuera del DOM

parent.append(table);

Podemos comparar la diferencia de rendimiento entre usar detach() o no en jsPerf.

También deberíamos tener en cuenta a la hora de usar o no detach() el efecto de que el navegador repinte la página para cada acción que realizamos si no lo usamos o que lo haga una sola vez si lo usamos.

appendTo()

Muchas veces necesitamos seguir usando un elemento después de crearlo. Es habitual ver este esquema:

$("body").append("<div class=\"elemento\"></div>");
$(".elemento").click(function()
{
	// Código
});

Esto obliga al navegador a crear un elemento, recalcular todo el DOM y luego volver a recorrerlo para encontrarlo. Sería mucho mejor utilizar la función appendTo(), que hace lo mismo que append(), pero devuelve el elemento insertado. Sería de esta forma:

$("<div class=\"elemento\"></div>").appendTo("body").click(function()
{
	// Código
});

data()

jQuery tiene la función data() para almacenar datos que podamos necesitar en los elementos del DOM. Es mucho mejor utilizar este recurso que almacenar los datos en los elementos y recuperarlos con las funciones text() o html().

var el = $("#elemento");
el.data("datos", 5);
var datos = el.data("datos");

Esta es la forma habitual de usarlo, pero utilizar $.data() es más rápido.

var el = $("#elemento");
$.data(el, "datos", 5);
var datos = $.data(el, "datos");

Podemos comparar la diferencia de rendimiento entre usar $.data() y $.fn.data() en jsPerf.

Aunque $.data() es más rápida que $.fn.data(), no siempre puede ser usado, ya que no acepta expresiones como parámetro sino que hay que pasarle un elemento.

Puedes leer más sobre este tema en nuestro artículo jQuery, optimizando para aumentar el rendimiento: uso excesivo.

Comentarios

3 comentarios. Comentar.

1. Elias el 25 Jul 2012 a las 16:11:00

Muy interesante ... gracias por los tips...

2. Anónimo el 15 Feb 2014 a las 05:43:41

yo siempre agregaba los elementos dentro del $.each() :O gracias por la informacion

3. Miguel el 17 Ago 2015 a las 17:10:28

Buenas colegas tengo una consulta con un remove.

Tratare de explicar lo mas simple posible que es lo que pasa.

Supongamos que tengo estos divs

<div id='contenedor'>

<div id='item1'>Hola</div>

<div id='item2'>Chau</div>

<div id='item3'>Eh!</div>

</div>

puedo por ejemplo sacar un alert del item1 y funcionaria.

alert($('#item1').html());

El problema se da cuando quiero remover estos items y recargarlos.

Hago lo siguiente.

$('#contenedor').children().remove();

$('#contenedor').append('<div id='item1'>Soy Nuevo</div>');

el resultado nuevo seria

<div id='contenedor'>

<div id='item1'>Soy Nuevo</div>

</div>

Cuando quiero usar el nuevo valor de item1 me devuelve 'undefined'

alert($('#item1').html());

Alguien sabe porque podria darse esto??

Desde ya gracias por la ayuda

Comentar

Comentar de forma anónima

Puedes comentar poniendo cualquier nombre o apodo, exceptuando los nombres de usuarios registrados. Máximo de 50 caracteres.

Comentar como usuario registrado

Registrarse. ¿Has olvidado tu contraseña?