2012-10-09 12 views
21

sigo leyendo lo mismo:¿Por qué es riesgoso almacenar datos como un atributo de un elemento?

"Almacenamiento de valores de la propiedad directamente sobre los elementos DOM es arriesgado debido a las posibles pérdidas de memoria."

Pero, ¿alguien puede explicar estos riesgos con más detalle?

+20

¿dónde has estado leyendo esto? – tybro0103

+0

?? yo pienso exactamente lo opuesto. el problema más común con pérdidas de memoria normalmente es la referencia circular. lea los comentarios en [http://perfectionkills.com/understanding-delete/](http://perfectionkills.com/understanding-delete/) –

+0

Estoy con @ tybro0103 en este; no creas todo lo que lees en la red. Almacenar datos en atributos 'data-' no va a causar pérdidas de memoria en sí mismo. Dicho esto, estoy votando @ la respuesta de Werner a continuación para citar una fuente confiable. – Sampson

Respuesta

15

(Por atributo, supongo que usted se refiere a las propiedades de los elementos DOM.)

son propiedades personalizadas en elementos DOM seguro?

Algunos navegadores no han limpiado los elementos DOM muy bien cuando se destruyeron. Por lo tanto, se conservaron referencias a otros elementos, el mismo elemento o grandes conjuntos de datos, lo que provocó filtraciones. Creo que esto se resuelve en gran medida en los navegadores más nuevos.

En cualquier caso, almacenar pequeñas cantidades de datos en un elemento es inofensivo, y puede ser muy conveniente, así que tome esa advertencia con un grano de sal.


está utilizando jQuery de .data() una alternativa segura?

No especialmente. Almacenar datos usando el almacén de datos personalizado de jQuery tiene su propio potencial para las pérdidas de memoria, y desafortunadamente no solo afectan a los navegadores antiguos.

Para evitar fugas, debe estar absolutamente seguro de que limpia un elemento .data() al destruir un elemento. Esto es automático cuando utiliza jQuery para destruir el elemento, pero si no lo hace, tendrá fugas de memoria que afectan a cada navegador.


Cuáles son algunos ejemplos que pueden causar fugas?

Digamos que hay un montón de .data() ligado al elemento #foo.Si utilizamos métodos de jQuery para eliminar el elemento, estamos seguros:

$("#foo").remove(); // associated .data() will be cleaned automatically 

Pero si hacemos esto, tenemos un multi-navegador compatible fuga:

var foo = document.getElementById("foo"); 
foo.parentNode.removeChild(foo); 

O si #foo es un descendiente de algún otro elemento cuyo contenido se borre sin jQuery, sería el mismo problema.

otherElement.innerHTML = ""; 

En ambos casos, jQuery no se utilizó para eliminar #foo, por lo que su .data() se desvincula de éste permanentemente el elemento, y nuestra aplicación tiene una fuga.


Así que si nunca utilizar la API de DOM directamente, estoy seguro?

Usted es más seguro, pero otra forma en que esto puede suceder es si cargamos más de una biblioteca de manipulación de DOM. Tengamos en cuenta que jQuery nos ayuda a hacer esto con el siguiente código:

var $jq = jQuery.noConflict(); 

Ahora podemos permitir que $ para referirse a prototypejs o mootools, y jQuery hace referencia $jq.

El problema es que esas otras bibliotecas no limpiarán los datos que jQuery estableció, porque no lo saben.

Así que si jQuery tiene algunos datos en #foo, y mootools se utiliza para destruir ese elemento, tenemos nuestra pérdida de memoria.


¿Qué pasa si yo nunca uso .data() en jQuery? ¿Eso me hace seguro?

Lamentablemente, no. jQuery usa el mismo mecanismo .data() para almacenar otros datos, como controladores de eventos. Por lo tanto, incluso si nunca hace una llamada al .data() para asociar algunos datos personalizados con un elemento, aún puede tener pérdidas de memoria causadas por los ejemplos anteriores.

La mayoría de las veces es posible que no note las fugas, pero dependiendo de la naturaleza del código, con el tiempo pueden crecer lo suficiente como para ser un problema.

+1

¿Puede explicar a qué se refiere cuando dice "limpiar .data() de un elemento usando jQuery cuando destruye el elemento" –

+0

@Anne: sí. Todos los datos, controladores, etc. que están asociados con un elemento se almacenan en un solo almacén de datos llamado 'jQuery.cache'. El enlace entre un elemento y sus datos en la tienda es un número de serie que jQuery coloca directamente en el elemento. Si usa jQuery para destruir un elemento, jQuery buscará los datos en la tienda y los eliminará. El problema es que si no usas jQuery para destruir un elemento, entonces el número de serie se pierde con el elemento y los datos asociados en 'jQuery.cache' permanecen huérfanos. OMI, esto es mucho más serio que almacenar un poco de datos en un elemento. –

+1

gracias por la respuesta. muy útil –

11

De acuerdo con la jQuery documentation:

En Internet Explorer anteriores a la versión 9, usando .prop() para establecer una propiedad de elemento DOM para que no sea un simple valor primitivo nada (número, cadena o boolean) puede causar pérdidas de memoria si la propiedad es no eliminada (utilizando .removeProp()) antes de que el elemento DOM se elimine del documento. Para establecer valores de manera segura en objetos DOM sin pérdida de memoria , utilice .data().

+0

Me refería a mi uso de $ ('# id'). Attr ('data-xx', 'yy'); ¿Es .prop algo más? –

+0

Encuentro que la respuesta aceptada en el siguiente enlace es una muy buena explicación sobre la diferencia entre .attr() y .prop(): http: // stackoverflow.com/questions/5874652/prop-vs-attr –

Cuestiones relacionadas