2012-08-07 16 views
5

Siempre que tenga un div contenedor con cientos de elementos de niños muy simples, tales como los siguientes:HTML DOMs, ids vs no ids?

<div id="stuffContainer" class="item-container"> 
    <div class="single-item"></div> 
    <div class="single-item"></div> 
    <div class="single-item"></div> 
    <div class="single-item"></div> 
    <div class="single-item"></div> 
    <div class="single-item"></div> 
    [...] 
</div> 

cabe indicar como un identificador único para cada actuación única daño elemento (cliente) de cualquier forma (significativa), ya sea representación, javascript o memoria sabia?

Por qué estoy preguntando: es posible que de vez en cuando necesite hacer referencia a elementos específicos, y estoy tratando de determinar si debo precalcular de antemano qué elementos necesitaré seleccionar, dándoles identificaciones y dejándolos. el resto, o simplemente asignar identificadores a todos ellos, lo que haría que el proceso sea más sencillo, pero me pregunto si esto puede ser un exceso de alguna manera.

Puntos de bonificación (si pudiera darles realmente) si alguien puede hablar sobre cómo los navegadores modernos manejan esto y por qué esto/no haría la diferencia en términos de cómo los navegadores procesan y administran el DOM.

+2

puede actualy dar puntos de bonificación, yopu parecer toi tienen un montón. acaba de establecer una recompensa ;-) – Pevara

+1

Hice [una simple prueba JSPerf] (http://jsperf.com/html-dom-id-vs-no-id) y obtengo resultados muy variados (la prueba podría no ser buena sin embargo), incluso en el mismo navegador (Chrome) en diferentes ventanas. El análisis del HTML podría tomar la mayor parte del tiempo, entonces [aquí hay una versión] (http://jsperf.com/html-dom-id-vs-no-id/2) donde cada elemento tiene el mismo número de atributos, pero los mismos resultados mixtos. Creo que en cuanto a rendimiento (como construir un índice, etc.) esto realmente no hace la diferencia. –

+0

@FelixKling interesante, gracias por armar las pruebas; en mi extremo (Chrome 20 y Firefox 14) parece que la versión sin identificación es ligeramente (muy ligeramente) más rápida. – Mahn

Respuesta

3

A lo sumo, supongo que las pocas cosas básicas que un navegador haría es asignar el ID como propiedad a cada elemento al construir la estructura DOM, así como almacenar los ID en una tabla hash para facilitar cosas como los selectores #id, document.getElementById() y las búsquedas Idref más adelante. No creo que esto vaya a causar ni una pequeña mella en el rendimiento observado o el uso de memoria, ya que las tablas hash y DOM están diseñadas para estar muy bien optimizadas.

Dicho esto, si las identificaciones no son necesarias en sus elementos en total, entonces simplemente no tiene sentido asignarles identificadores; en su lugar, vas a terminar con una gran cantidad de hinchazón de marcado. Como Dan Davies Brackett menciona, será, obviamente, causará una desaceleración, ya que depende de la conexión del cliente.

Si puede permitirse hacer referencia a estos elementos utilizando los selectores CSS, siempre puede usar :nth-child() para buscar niños específicos. Si necesita admitir navegadores más antiguos, siempre hay una solución CSS2. Ver estas preguntas:

+2

Me gusta el término "rendimiento observado", lo estoy robando totalmente. Sin embargo, sin votos :( – Esailija

+0

Gran respuesta, gracias. Tenía la esperanza de que pudiera obtener un poco de Chrome o Mozilla para acelerar y publicar una respuesta técnica detallada sobre cómo esto no afectaría el rendimiento en un navegador moderno, pero supongo que eso no va a suceder. :-) – Mahn

+0

@Mahn: Bueno, hay al menos uno de cada uno que pasa de vez en cuando. Tal vez si tiene suerte ... – BoltClock

1

No hay degradaciones de rendimiento significativas del uso de id atributos, incluso cuando se utiliza cientos de veces. Aunque sería un poco más rápido seleccionar a mano los elementos que necesita identificar de manera única, en mi opinión, la mejora en el rendimiento no justificaría el tiempo adicional requerido para hacerlo.

Dicho esto, no estoy seguro de que los atributos id sean incluso necesarios en este caso. Si se va a usar jQuery, podría seleccionar el cuarto elemento, por ejemplo, usando el siguiente código:

$('.single-item').eq(3); 
+0

Probablemente seleccionarlos por id aún sería más rápido que usar la ecuación de jQuery, ¿o no? – Mahn

+0

@Mahn - Sí, pero una vez más, no creo que la mejora en el rendimiento justifique pasar el tiempo necesario para agregar cada atributo 'id'. Además, eliminar los atributos 'id' disminuiría el tamaño del archivo. – jeff

2

Como BoltClock implica, la respuesta a la mayoría de preguntas de desempeño es 'medirlo!'. Dicho esto, omitió un posible eje de medida: tamaño de descarga. Agregar atributos de ID a más elementos de los necesarios se agregará al peso de su byte, sobre todo porque se requiere que los elementos sean únicos (lo que significa que no se comprimirán tan bien como los atributos no únicos).

+0

¡Un gran punto, gracias! – Mahn

0

El uso de id's en todo sería un poco exagerado en este caso. Entiendo de dónde vienes, pero si utilizas un lenguaje como jQuery, seleccionar los niños sería fácil teniendo en cuenta la estructura.Aquí hay un ejemplo de cómo puede saber que se hace clic en uno de los divs:

$('.single-item').click(function() 
{ 
    var yourClickedDiv = $(this); 
    // execute the rest of your code here 
}); 

Esto es sólo un pequeño ejemplo, pero como se puede ver, que son capaces de acceder a cada div para lo que hay que hacer . Esto mantendrá el archivo html menos desordenado de las etiquetas de identificación excesivas, junto con mantener el tamaño de su archivo un poco más pequeño (sin mencionar le ahorrará el dolor de cabeza de generar cada identificación única).

+1

Ese código jQuery es muy problemático en cuanto a rendimiento. Si tiene cientos de elementos con esa clase, debe usar [event delegation] (http://api.jquery.com/on/#direct-and-delegated-events). – bfavaretto

+0

Algo contradictorio para escatimar en atributos de id. Para ahorrar ancho de banda, luego incluir una biblioteca de 4.000 líneas como alternativa. – RobG

2

La Q original no es muy específica sobre el contenido/propósito y debe haber una variación, dependiendo de la IMO. Definitivamente estoy en desacuerdo con la respuesta aceptada actual en un punto. Al recorrer y adjuntar nuevos ID a una tonelada de HTML que ya se ha procesado, se pueden generar cantidades masivas de cálculos de reflujo, que podrían ponerse feas dependiendo de lo que representa 'stuffContainer'.

Construir con los ID de Primera Desde servidor o inyectar tan solo bloque en el lado del cliente si es necesario hacerlo

Como regla general, evitar golpear el DOM con los cambios en repetidas ocasiones si puede evitarlo. Los ID construidos de antemano en el servidor son bastante insignificantes en cuanto al navegador que carga la página, IMO. Claro, es una tabla de hash más grande, y en consecuencia más lenta, pero si hablamos de cientos y no de decenas de miles, dudo seriamente que te vayas a dar cuenta.

Un enfoque más eficiente del lado del cliente en el caso de una lista de selección construida a partir de datos sería construir primero como una cadena, con ID y todo, y luego asignar a innerHTML de un contenedor o si como algunos de Mis colegas de js chat, tienen un extraño problema con innerHTML en todos los casos de uso posibles, aunque ahora está en la especificación, al menos compilar y anexar primero a un fragmento de documento. y luego añádalo a su contenedor.

Data-atributos o clases Más de ID de

OMI, el olor-factor no es tanto sobre el rendimiento, sino más bien la hinchazón HTML y la creación de una dependencia de identificación donde se necesita ninguna, bloqueando de este modo algo más que podría encontrar una ID personalizada en uno de sus divs de un solo elemento es útil. Los identificadores son definitivamente la forma ideal de reducir la búsqueda de elementos en JavaScript, pero en los casos de contenedores con contenido obtendrá más flexibilidad de los contenedores ID que los que identifiquen cada elemento secundario. La ganancia de rendimiento de un paso frente a dos pasos no vale la pena el costo de flexibilidad de la aplicación de identificadores genéricos a los elementos.

Como alternativa, puede usar clases con valores únicos o el atributo de datos, p. 'data-itemId = "0"'. Para conjuntos de HTML más pequeños, como una lista de selección personalizada donde los ID están conectados a algún sistema de indexación del lado del servidor para facilitar la actualización de datos, tendería a favorecer este enfoque altamente visible ya que facilita la comprensión de la arquitectura, pero agrega mucho de atributos innecesarios para rastrear escenarios en los que podrían estar involucrados cientos o miles de elementos.

o, idealmente, (en la mayoría de los casos), Delegación Evento

más idealmente, la OMI, se evita por completo atributos adicionales en los casos en que sólo se preocupan por el elemento de artículo único hijo que está haciendo Clicks y no lo es 'ID' es o el orden en que esos contenedores de elementos individuales permanecerán estáticos y usted puede asumir con seguridad que las posiciones son los ID efectivos. O bien, otro escenario en el que esto podría funcionar con un conjunto de elementos únicos no estáticos es si tiene datos de un solo elemento en una matriz de objetos que se barajan y luego se usan para construir y reemplazar HTML en géneros iniciados por el usuario que siempre vincula el orden del HTML a otras dependencias de seguimiento de datos.

El enfoque no Jquery (no probado):

var myContainer = document.getElementById('stuffContainer'); 
//ignore following indent goof 

    myContainer.addEventListener('click', function(e){ 
     var 
      singleItem, 
      elementOriginallyClicked = singleItem = e.target, 
      stuffContainer = this; 

     //anything clicked inside myContainer will trigger a click event on myContainer 
     //the original element clicked is e.target 
     //google 'event bubbling javascript' or 'event delegation javascript' for more info 

     //climb parentNodes until we get to a single-item node 
     //unless it's already single-item that was originally clicked 
     while(!singleItem.className.match(/[=\s'"]single-item[\s'"]/g)){ 
      singleItem = singleItem.parentNode; 
     } 

     //You now have a reference to the element you care about 

     //If you want the index: 

     //Get the singleItem's parent's childNodes collection and convert to array 
     //then use indexOf (MDN has normalizer for IE<=8) to get the index of the single-item 

     var childArray = Array.prototype.slice.apply(stuffContainer.childNodes,[0]), 
     thisIndex = childArray.indexOf(singleItem); 

     doSomethingWithIndex(thisIndex); 
     //or 
     //doSomethingWithDOMObject(singleItem); 

    }); 

O sencilla jQuery estilo de delegación (también, no probado):

$('#someContainer').on('click','.single-item', function(){ 
    var $_singleItem = $(this), //jq handles the bubble to the interesting node for you 
    thisIndex = $_singleItem.index(); //also getting index relative to parent 

    doSomethingWithIndex(thisIndex); 
    //or 
    //doSomethingWithJQObject($_thisItem); 
}); 
+0

Estoy de acuerdo con casi todo lo que ha escrito y tiene mis votos, pero tengo que ser honesto, estaba buscando específicamente la respuesta sobre cómo reaccionaría el navegador siempre que los ID se generaran en el lado del servidor cuando publiqué la pregunta, que @BoltClock cubre más directamente. Pero aceptaría tu respuesta y también podría aceptar dos veces. – Mahn

+0

Sin problema Upvotes apreciado. Aprendí a abrazar ser la criada del TLDR y no la novia. –

Cuestiones relacionadas