2010-08-04 14 views
9

Recientemente necesité agregar algunos datos a LI elements creado dinámicamente. En mi primera instancia, solía .data() de una manera como

var _newli = $('<li>foobar</li>'); 
_newli.data('base', 'ball'); 
// append _newli to an `ul` 

que era .. terriblemente lento. Esta lógica ocurre en un ciclo que puede crecer fácilmente hasta más de 500 elementos, ¡tomó siglos! A veces incluso rompió el marco de tiempo de ejecución de javascript.

Así que cambié a $.data(). De alguna manera, adjuntar datos a un objeto con eso es como 8x más rápido que hacerlo a través de la llamada al método .data(). Así que ahora parecía que

var _newli = $('<li>foobar</li>'); 
$.data(_newli[0], 'base', 'ball'); 
// append _newli to an `ul` 

Eso era/es de hecho más rápido, pero aún así tomó como 3-4 segundos (!) Para construir todos mis elementos (en mi código real no son como las llamadas a 6 $. datos por elemento).

Así que estaba realmente atrapado con eso, me pregunté por qué diablos usar .data() o $.data() de todos modos? Podría simplemente adjuntar mis datos al DOM object. Así que hice

var _newli = $('<li>foobar</li>'); 
_newli[0].base = 'ball'; 
// append _newli to an `ul` 

Voila, wow para mi sorpresa, que era increíblemente rápido! No podía creer que esto funcionara tan bien sin ninguna desventaja. Entonces, de eso se trata mi pregunta realmente. No encontré ninguna desventaja para esta técnica hasta ahora en la red. Hay lecturas sobre referencias circulares que puede crear de esta manera, pero AFAIK "solo" en IE y solo si se refiere a objects.

¿Alguna opinión expertos?

actualización

Gracias por los buenos comentarios y mensajes chicos. Actualización breve @patrick dw:

Tienes razón, estaba pasando la subcapa DOM element al usar $.data(). Ni siquiera funciona con objetos jQuery, al menos no como se esperaba. La idea de usar un objeto y pasarlo a través de $.date() Lo tuve yo mismo, pero una vez más quedé tan conmocionado por la diferencia de rendimiento que decidí ignorar el método .data() como siempre.

+0

Si hubo * "6 llamadas a $ .data por elemento" *, ¿hay alguna razón por la que no haya hecho una sola llamada y haya ingresado un objeto por el valor que contiene todas las propiedades que ¿querer? '$ .data (_newli, 'myvalues', {'base': 'ball', 'basket': 'ball', 'foot': 'ball'});' – user113716

+2

En una charla, John dice que es lenta , y sugiere hacer 'var data = $ ('selector'). data(); data ['foo'] = 'bar'; data ['bar'] = 'foo'; etc.', para que solo tengas ** un ** acceso a él. solo para tu información. –

+0

@jAndy - Debería pasar elementos DOM a '$ .data()'. No objetos 'jQuery'. Me pregunto si eso también tiene un impacto en el rendimiento. '$ .data (_newli [0], 'base', 'ball');' – user113716

Respuesta

3

Tiene la razón referencias circulares, eso no es un problema fuera de IE, y en IE solo se convierte en un problema cuando JavaScript tiene una referencia a un objeto DOM, y se asigna un objeto JS a uno de las propiedades del objeto DOM. Creo que esto se puede resolver simplemente anulando cualquier referencia en JS al objeto DOM.

El método $().data() es una envoltura excesivamente complicado para $.data() (ver jQuery.fn.data: http://github.com/jquery/jquery/blob/master/src/data.js#L126, que a su vez llama a jQuery.data: http://github.com/jquery/jquery/blob/master/src/data.js#L20), por lo que el corte que el hombre medio ahorrará una cantidad no trivial de tiempo, especialmente si es por hacer 500 veces

En este caso, el método $().data('foo', 'bar') no hace mucho más que el.foo = 'bar'. Haz lo que es más rápido.

0

Estos pueden ayudar:

Y lea la siguiente sobre el uso de un DTD personalizado:

En resumen, la mayor parte del tiempo no creo que tenga problemas al usar atributos personalizados. La mayoría de los navegadores sensibles/actuales estarán a la altura.Diré, I hizo tener problemas con una aplicación web que desarrollé para MobileSafari, lo que me obligó a recurrir al uso de $.data elementos ocultos. Afortunadamente, no tenía más de 500 elementos, sino más bien cinco o seis.

+1

Supongo que estamos hablando de dos storys diferentes. Si adjunta algunos datos a 'element.somedata = {foo: 5};' no hay 'atributo' creado para eso. Es como mezclar 'ECMAland' y' DOMland' de alguna manera, ya que un 'elemento DOM' se trata como un objeto en ECMAscript. – jAndy

Cuestiones relacionadas