2010-01-30 15 views
11

Tengo una gran cantidad de elementos que se generan y se hace referencia (mouseover, clics, cambios de posición) muchas veces.¿Debo almacenar en caché document.getElementById() en una variable o llamarlo cada vez?

Tengo los ID de esos elementos a mano. ¿Es aconsejable almacenar las llamadas document.getElementById(ID) en una variable, o es más rápido/tan rápido/lento para llamar al document.getElementById() cada vez?

var app = []; 
var app.elements = []; 
//i can store ['id1', 'id2', 'id3'] 
//OR ['id1' => document.getElementById('id1'), 'id2' => document.getElementById('id2'), 'id3' => document.getElementById('id3')] 
+0

Ninguno de los dos debe usar jQuery! – Aaronaught

+0

Estoy usando jQuery. Para mejorar el rendimiento: la misma pregunta: ¿debo almacenar en caché el objeto jQuery ($ ('# id1')) o debo llamar a $ ('# id1') cada vez que lo necesito? – Ropstah

Respuesta

8

Debe, por supuesto, volver a utilizar la referencia siempre que sea posible, pero puede que tenga que obtener una nueva referencia en cada cuerpo de la función.

Ejemplo:

var e1 = document.getElementById('id1'); 
e1.innerHTML = 'test'; 
e1.className = 'info'; 

Si se mantiene referencias más tiempo, es posible que ya no funcionan. Si, por ejemplo, obtiene innerHTML para una parte de la página y la almacena de nuevo, todos los elementos en esa parte se eliminan y vuelven a crear. Si tenía una referencia a uno de los elementos en esa parte, ese elemento ya no existe.

// This will recreate all elements inside the 'parent' element: 
document.getElementById('parent').innerHTML += 'test'; 
+0

Este es un buen punto, y me gustaría agregar que nunca se sabe quién, o qué, va a cambiar un nodo DOM debajo de usted. Siempre estoy a favor de obtener la referencia explícitamente para reducir los errores y mejorar la legibilidad. Si está manejando muchos nodos en una situación de alto rendimiento, es posible que desee asignarlos a la memoria. –

+0

Serán alrededor de 500 artículos, pero se administrarán correctamente. Estoy usando jQuery y la mayoría de las veces el objeto será $ (jqueryfied) para que pueda llamar a funciones como position(). ¿Pasa lo mismo para almacenar el objeto $ ('# id1') en la memoria? – Ropstah

+0

Oh, ahora tiene sentido. Me preguntaba por qué el almacenamiento en caché se rompe en las llamadas a funciones. (Por supuesto, estaba creando nuevos elementos allí). – Dallaylaen

2

Es sin duda más rápido para almacenar los elementos de una variable, pero no por un amplio margen. Esto es algo diferente de un caso a otro y debe adaptarse para cada uno individualmente.

Tal vez el factor más importante es la legibilidad, creo que el acceso a los elementos directamente es más legible.

theMainButton.style.color = "red"; 
// vs. 
document.getElementById("theMainButton").style.color = "red"; 
+0

Estoy buscando ganancias de rendimiento aquí. El código está guardado en funciones y no necesita lectura :) – Ropstah

+2

TODO el código necesita lectura, a menos que esté escrito a la perfección la primera vez, nunca necesite ser modificado o ampliado, nunca necesita nuevas características, y nunca necesitará ser entendido . :) – Eddie

+0

¿Sería aún más rápido si lo está almacenando en una matriz dispersa/mapa? Lo pregunto porque getElementById ya tiene los ids en la memoria caché, así que no estoy seguro de si hay alguna ganancia para tener un caché de los elementos que ya tienen una identificación (búsqueda más rápida) que guarda los elementos que se iban a buscar antes de tiempo, pero en el proceso de buscar los datos, esencialmente está haciendo lo mismo que getElementById ... – Dmitry

3

getElementById devuelve un nodo de elemento, que es esencialmente solo un objeto JavaScript. Puede asignar este objeto a una variable, lo que significa que la variable apuntará a este objeto cada vez que escriba esa variable en una etapa posterior. Así,

var id1 = document.getElementById('id1'); 

id1 ahora se refiere al elemento DOM con un id de id1. Si no se encontró ningún elemento con ese id, entonces document.getElementById devuelve nulo.

Si los elementos permanecen dentro del DOM y no se reemplazan, tiene sentido almacenarlos en una matriz, para que pueda hacer referencia a ellos tantas veces como lo desee sin ningún costo de rendimiento.

Si le ayuda, puede crear una función simple que lo haga por usted:

function getElementsByIds(/* id1, id2 ... */) { 

    var elems = []; 

    for (var i = 0, l = arguments.length; i < l; i++) { 
     elems[i] = document.getElementById(arguments[i]); 
    } 

    return elems; 

} 

app.elements = getElementsByIds('id1', 'id2', 'id3'); 
3

no hay una única respuesta correcta a esta pregunta. Todo depende de con lo que tienes que trabajar. Si está trabajando con una página que tiene una gran cantidad de elementos en el árbol DOM, es mejor guardar en la memoria caché las referencias y volver a utilizarlas, para acelerar el tiempo de búsqueda. Si está trabajando en una página pequeña, es mejor buscar elementos sobre la marcha y minimizar el consumo de memoria del navegador.

También depende de los navegadores a los que apunta. Por ejemplo, las versiones más recientes de Firefox tardan un poco en ajustar un elemento por primera vez, pero almacenan en caché la referencia internamente, por lo que la próxima vez que vaya a buscarla, será casi instantánea. IE, por otro lado, no almacena en caché los valores de búsqueda, pero su tiempo de búsqueda es mucho más rápido que Firefox en el primer intento.

Muchos frameworks modernos almacenarán en caché los elementos que encontraste para ti. Sin embargo, yo personalmente sigo prefiriendo usar document.getElementById la mayor parte del tiempo.Lo que hago, cuando necesito para almacenar en caché valores de búsqueda es el siguiente:

function registerElement(id) 
{ 
    if (!this["get_" + id]) 
     this["get_" + id] = function() { 
      var element = document.getElementById(id); 
      this["get_" + id] = function() {return element;}; 
      return element; 
     } 
} 

Se utiliza esta llamando registerElement y se lleva una identificación del elemento. Cuando necesite recuperar el valor, llame al ID de get_element que aprobó y, en la primera ejecución, buscará el elemento y lo guardará en caché, en cada llamada consecutiva solo devolverá el valor en caché.

Cuestiones relacionadas