Foros del Web » Programando para Internet » Javascript »

Eliminar script y vaciar memoria utilizada por este

Estas en el tema de Eliminar script y vaciar memoria utilizada por este en el foro de Javascript en Foros del Web. Estoy implementando una web donde se carga todo el contenido vía AJAX en donde a su vez debo incluir las dependencias de cada sección solicitando ...
  #1 (permalink)  
Antiguo 03/09/2011, 01:30
de-troit
Invitado
 
Mensajes: n/a
Puntos:
Eliminar script y vaciar memoria utilizada por este

Estoy implementando una web donde se carga todo el contenido vía AJAX en donde a su vez debo incluir las dependencias de cada sección solicitando al servidor las hojas de estilos y los scripts js. Ahora si se llega a visitar una sección que ya ha sido visitada antes (por ende sus dependencias), no haría falta volver a cargarlas ya que ya fueron importadas antes, el real problema es que si se quiere cargar otra sección los script cargados anteriormente de otras secciones quedarán ocupando memoria, entonces quería saber si hay alguna forma de eliminar estos script y la memoria que ocuparon (como cerrar la página pero sin cerrarla) para optimizar recursos.

Hay alguna posibilidad de hacer esto? Seguiré averiguando en internet, si encuentro la solución lo pondré.

Saludos y muchas gracias por su atención ;)
  #2 (permalink)  
Antiguo 03/09/2011, 07:23
Avatar de _cronos2
Colaborador
 
Fecha de Ingreso: junio-2010
Mensajes: 2.062
Antigüedad: 14 años, 5 meses
Puntos: 310
Respuesta: Eliminar script y vaciar memoria utilizada por este

Puedes eliminar el tag script, pero eso no significa que el contenido vaya a dejar de ocupar memoria. Una vez cargado, la única manera de destruirlo sería asignando cada variable y función a null. Lo mejor para esto es que uses un namespace, así sólo tendras que hacer namespace = null y todo lo de su interior se borrará también.
Saludos (:
__________________
" Getting older’s not been on my plans
but it’s never late, it’s never late enough for me to stay. "
Cigarettes - Russian Red
  #3 (permalink)  
Antiguo 03/09/2011, 07:49
Avatar de Panino5001
Me alejo de Omelas
 
Fecha de Ingreso: mayo-2004
Ubicación: -34.637167,-58.462984
Mensajes: 5.148
Antigüedad: 20 años, 5 meses
Puntos: 834
Respuesta: Eliminar script y vaciar memoria utilizada por este

Añado a lo dicho por _cronos2: si se crean elementos vía DOM también habrá que removerlos uno a uno, previa remoción de sus eventos si es que los tienen (esto último es vital para la gestión de memoria de Explorer, que maneja 2 mundos: DOM y COM).
  #4 (permalink)  
Antiguo 03/09/2011, 15:18
de-troit
Invitado
 
Mensajes: n/a
Puntos:
Respuesta: Eliminar script y vaciar memoria utilizada por este

Es justo lo que pensé y lo que leí en una parte.

Ejecutar siempre las acciones dentro de una función anónima cuando sea posible podría ayudar cierto? ya que al finalizar la función las variables de destruyen, cierto?

Otra opción que se me ocurre es manejar todas las variables dentro de un objeto, es decir como atributos y después vaciar ese objeto, así se irían todas las variables, es buena opción, no creen? así me evito el tener que poner cada variable con valor null. También el eliminar todos los elementosy sus eventos que estén dentro de la zona de carga.

Haciendo estas 2 cosas se liberará toda o casi toda la memoria ocupada?

No quiero que haya una sobrecarga, ya que debo cargar los script nuevamente cada vez que el usuario cambie de sección en la web (menu).

Espero comentarios y/o soluciones. Saludos!
  #5 (permalink)  
Antiguo 03/09/2011, 15:20
de-troit
Invitado
 
Mensajes: n/a
Puntos:
Respuesta: Eliminar script y vaciar memoria utilizada por este

Cita:
Iniciado por Panino5001 Ver Mensaje
...(esto último es vital para la gestión de memoria de Explorer, que maneja 2 mundos: DOM y COM).
Podrías aclararme lo del COM? C...? Object Model.

Cita:
Iniciado por _cronos2 Ver Mensaje
Lo mejor para esto es que uses un namespace, así sólo tendras que hacer namespace = null y todo lo de su interior se borrará también.
Saludos (:
Con namespace te refieres a crear las variables como atributos de un objeto para después declarar objeto = null y borrar todo así dije en el post anterior?

Saludos!
  #6 (permalink)  
Antiguo 03/09/2011, 15:45
Avatar de Panino5001
Me alejo de Omelas
 
Fecha de Ingreso: mayo-2004
Ubicación: -34.637167,-58.462984
Mensajes: 5.148
Antigüedad: 20 años, 5 meses
Puntos: 834
Respuesta: Eliminar script y vaciar memoria utilizada por este

Con respecto a DOM/COM, te dejo estos enlaces: http://msdn.microsoft.com/en-us/libr...(v=vs.85).aspx
http://es.wikipedia.org/wiki/Component_Object_Model
Con respecto a namespaces:
http://es.wikipedia.org/wiki/Espacio_de_nombres
http://dustindiaz.com/namespace-your-javascript/
  #7 (permalink)  
Antiguo 04/09/2011, 17:08
de-troit
Invitado
 
Mensajes: n/a
Puntos:
Respuesta: Eliminar script y vaciar memoria utilizada por este

Cita:
Iniciado por Panino5001 Ver Mensaje
Con respecto a DOM/COM, te dejo estos enlaces:
...
Con respecto a namespaces:
...
Muchas gracias Panino5001, era exactamente eso a lo que me refería, estoy claro con los namespaces.

Voy a leer luego acerca del COM de Microsoft. Muchas gracias :)

Creo que la mejor manera de trabajar es usando namespaces, el problema, aunque en realidad no lo es tanto, es que estoy implementando este sistema de carga y otros complementos en un plugin para jquery y con esto estaría obligando al desarrollador que use el plugin a trabajar con namespaces para poder liberar la memoria, sería como quitarle un poco la libertad para desarrollar pero al parecer es la única forma de poder liberarla, aunque trabajar con namespaces es una buena práctica. Qué piensan al respecto?

Saludos y muchas gracias ;)
  #8 (permalink)  
Antiguo 04/09/2011, 21:56
 
Fecha de Ingreso: julio-2011
Ubicación: Zapopan, Jal. MX
Mensajes: 316
Antigüedad: 13 años, 4 meses
Puntos: 32
Respuesta: Eliminar script y vaciar memoria utilizada por este

También puedes ir borrando las variables haciendo así:

Código Javascript:
Ver original
  1. miVariable = null;

Con ello haces que la variable ya no ocupe nada en memoria, puedes aplicarlo en funciones, objetos, métodos, etc.

Saludos
  #9 (permalink)  
Antiguo 04/09/2011, 22:39
Avatar de zerokilled
Javascripter
 
Fecha de Ingreso: abril-2009
Ubicación: Isla del Encanto, La Borinqueña [+>==]
Mensajes: 8.050
Antigüedad: 15 años, 7 meses
Puntos: 1485
Respuesta: Eliminar script y vaciar memoria utilizada por este

buenas,
@ixtremelt... esta claro que para vaciar la variable debes asignar un valor tal que undefined o null. no obstante, es un enrollo administrar todas las variables y luego tener un bucle para vaciarlas todas. de ahí que la idea es usar un "namespace", porque es una sola variable de la que se tiene que ocupar, en teoría. sin embargo, hay otros aspectos adicionales a considerar y principalmente es cuando sucede el derrame de memoria (memory leak) que por lo general sucede con closure y otras técnicas. por eso @panino menciona acerca de COM. microsoft tiene un artículo que habla sobre diferentes patrones que producen el derrame de memoria en iexplorer. http://msdn.microsoft.com/en-us/libr...(v=vs.85).aspx la solución, evitar los patrones que producen el derrame, o encargarse de ellos para poder liberarlos. pero en definitiva que lo mejor sería un namespace, al menos mi opinión.
__________________
la maldad es una virtud humana,
y la espiritualidad es la lucha del hombre contra su maldad.
  #10 (permalink)  
Antiguo 05/09/2011, 04:41
de-troit
Invitado
 
Mensajes: n/a
Puntos:
Respuesta: Eliminar script y vaciar memoria utilizada por este

Gracias por tu post zerokilled, varios concordamos en que usar namespaces es la mejor solución.

Ahora tengo un problema y necesito que ustedes como desarrolladores con experiencia (con toda la que tienen) me den su opinión acerca de algo, les contaré qué es:

Tengo actualmente la misión de armar un sitio web (administrable) que se vea super moderno, para esto se me ocurrió que en vez de cargar de forma normal el sitio web al entrar a otra sección del menu (donde se cambia la url en la barra de direcciones y carga la otra página), la web se cargara toda en una capa div contenedora del contenido sin recargar la página (vía ajax). La idea es armar un sitio web normal, donde cada sección sea igual a la otra y sólo cargo con ajax ($.load) el div contenedor de información, con esto puedo dar la posibilidad al sitio de ser navegado de la forma tradicional o cargándose dinámicamente (esto controlado con unos parámetros en el link). Después de llevar programada las funciones necesarias para obtener los parámetros por link y controlar el cómo se entra a las secciones con javascript y también al ver que se extendía la programación, pensé que cuando quiera armar otro sitio web igual iba a tener que programar todo de nuevo pero acorde al nuevo sitio, así que se me ocurrió adaptar todas estas funciones en un plugin para jquery para poder usarlo en mis posteriores desarrollos, para que así pueda ser usado sobre cualquier contexto (cualquier web). El problema que surge con esto es que debo cargar las dependecias (que no sé cuales serán, debo inventar un método para saber cuales serán) y cargarlas, y luego cuando se cambie de sección vaciar la memoria ocupada por las dependencias cargadas anteriormente (scripts, css) y cargar las nuevas dependencias dinámicamente en coordinación con la sección que se cargue. Para esto lo que no debe ocurrir jamás es un overload o sobrecarga de dependencias. La única forma que se me ocurre es que al usar el plugin el desarrollador que use el plugin programe todo usando namespaces y luego a través de una función que implementé pueda "registrar" los namespaces (algo parecido al patrón registry de php), en donde tengo acceso por referencia a todos los namespaces usados en esa sección, y así al cargar otra sección, libero la memoria que ocupan estos namespaces igualando todos los atributos de cada uno como null. Luego me queda el problema de resolver la sobrecarga de css.

Ahora mi pregunta es: ¿Les parece una buena idea implementar este método de carga? Me refiero a que se cargue todo dinámicamente, lo digo sólamente por el tema de la sobrecarga, lo demás es solucionable, pero el tema que me preocupa es la sobrecarga, no puedo programar un plugin que cargue la memoria con basura sin nunca deshacerse de ella. La idea es que el terminarlo lo pueda debuguear y mejorar para después ponerlo en línea porsi a alguien más le sirve y lo quiere mejorar, asi puedo contribuir con mi granito de arena a la comunidad desarrolladora :P, ya que me siento basura sólo usando el trabajo de otros hahaha. Si quiero hacer esto debo hacerlo bien.

(Por si el plugin también tiene otras características como un preloader y una consola de errores importantes para facilitar el desarrollo).

Espero sus opiniones y/o sugerencias al respecto.

Saludos!
  #11 (permalink)  
Antiguo 05/09/2011, 05:46
Avatar de Panino5001
Me alejo de Omelas
 
Fecha de Ingreso: mayo-2004
Ubicación: -34.637167,-58.462984
Mensajes: 5.148
Antigüedad: 20 años, 5 meses
Puntos: 834
Respuesta: Eliminar script y vaciar memoria utilizada por este

Mi opinión es que te estás complicando demasiado. No veo la necesidad de cargar los scripts de manera independiente salvo que sean demasiado grandes. Y, si este es el caso, ya tenés la solución para anular las variables usando un namespace y quitando del DOM el tag script cargado. En cuanto al css: lo mejor es usar una única hoja de estilos sin carga dinámica, ya que es lógico pensar que todo tendrá una estética común y, entonces, la mejor opción es reutilizar estilos. En cuanto al DOM, sobreescribir la capa principal (div) con innerHTML ya eliminó todos tus problemas de guardado en memoria de los elementos DOM (podés comprobar que eso nulifica todos los elementos creados en esa capa). Te queda la gestión de eventos. Cada vez que los asignes deberías guardar una referencia a los mismos dentro de un objeto para, en el momento adecuado, recorrer ese objeto e ir eliminándolos (removeEventListener y detachEvent).
  #12 (permalink)  
Antiguo 05/09/2011, 07:29
Avatar de Aijoona
Colaborador
 
Fecha de Ingreso: mayo-2011
Ubicación: Buenos Aires
Mensajes: 779
Antigüedad: 13 años, 6 meses
Puntos: 343
Respuesta: Eliminar script y vaciar memoria utilizada por este

Si necesitas liberar memoria probablemente estés haciendo algo mal. Como te mencionaron varias veces, tu problema es netamente de arquitectura.

Para tu caso, te recomiendo que le pegues un vistazo a Backbone.js, una librería que justamente te provee la arquitectura básica (models, routing, etc) para que solo tengas que ocuparte de la lógica de negocio.

Como experiencia personal te puedo decir que el próximo te saldrá mejor jaja
__________________
blog | @aijoona
  #13 (permalink)  
Antiguo 05/09/2011, 13:51
de-troit
Invitado
 
Mensajes: n/a
Puntos:
Respuesta: Eliminar script y vaciar memoria utilizada por este

Panino5001: Como uso jQuery para eliminar los eventos bastaría con remover los eventos de todo lo que esté en el div que contiene la info dinámica (llamémosle #content) con la función unbind(), pero es más simple aún removiendo el div#content con la función remove() que a su vez también elimina los listeners para los eventos que se generarán, eso es asunto arreglado.

Por qué es necesario cargar los scripts independientemente? porque al cagar una nueva sección necesito que se agreguen esas funciones (namespaces del usuario) porque al solicitar la página de la forma $('#content').load('solicitado.html #content') no se cargan los scripts, entonces debo hacerlo todo manualmente, recuerda que la página se carga vía ajax, es decir, nunca nos salimos del index, y cada vez que se pinche en un menu se solicita el div #content del documento html y lo inserto en #content del index. Entiendes por qué es estrictamente necesario hacerlo así? Luego debo eliminarlos cuando se cambie de menu, porque se necesitarán otras funciones y no las cargadas anteriormente, y si cargo y cargo cada vez que se entre a un menu y no vacio la memoria ocupada podría generarse un overload, y eso sería catastrófico.

Lo de la hoja de estilo CSS común para todo no puede ser, porque recuerda que estoy pensando el plugin para cualquier caso, en donde puede coincidir los estilos como puede que no, lo único que me queda sería cargarlos dinámicamente al igual que los scripts JS.

Me entiendes? Espero tu comentario.

Saludos! :)
  #14 (permalink)  
Antiguo 05/09/2011, 15:21
Avatar de Panino5001
Me alejo de Omelas
 
Fecha de Ingreso: mayo-2004
Ubicación: -34.637167,-58.462984
Mensajes: 5.148
Antigüedad: 20 años, 5 meses
Puntos: 834
Respuesta: Eliminar script y vaciar memoria utilizada por este

Entiendo. Pero entonces ya tendrías todo resuelto, no? Porque si usás en todos los scripts el mismo espacio de nombres e incluís los tags script con document.createElement (no domino jQuery) y les asignás un id para removerlo antes de cargar uno nuevo y nulifícás el espacio de nombres antes de eliminarlo (o lo sobreescribís con el nuevo script), y si hacés lo mismo con los elementos link correspondientes a tus estilos css (remover los viejos elementos link antes de cargar los nuevos), qué duda te quedaría entonces?
  #15 (permalink)  
Antiguo 06/09/2011, 13:15
de-troit
Invitado
 
Mensajes: n/a
Puntos:
Respuesta: Eliminar script y vaciar memoria utilizada por este

En primer lugar el namespace no tendrá el mismo nombre porque está pensado para todos los casos, es por eso que implementé una función llamada registry que registra el namespace (si programas en php y conoces patrones piensa que es bien similar con la diferencia que no se registran instancias si no los namespaces), entonces así puedo vaciar los namespaces.

Ahora la duda que me queda es con los estilos css, no sé eliminando el tag se elimina en realidad el css, no quiero que se vaya acumulando o que hayas topes de reglas.

Qué dices al respecto?

Insisto que todo está pensado para todos los casos, no sé si todas las hojas de estilo tendrán el mismo nombre o no.

Saludos!
  #16 (permalink)  
Antiguo 06/09/2011, 15:28
Avatar de _cronos2
Colaborador
 
Fecha de Ingreso: junio-2010
Mensajes: 2.062
Antigüedad: 14 años, 5 meses
Puntos: 310
Respuesta: Eliminar script y vaciar memoria utilizada por este

Quizás accediendo al tag mediante document.styleSheets y borrando cssRules vacíe la memoria, pero es algo que se me acaba de ocurrir así que puede que no tenga ningún efecto. Sería bueno que alguien con más experiencia lo corroborara/desmintiera.
Saludos (:
__________________
" Getting older’s not been on my plans
but it’s never late, it’s never late enough for me to stay. "
Cigarettes - Russian Red
  #17 (permalink)  
Antiguo 06/09/2011, 15:35
Avatar de Panino5001
Me alejo de Omelas
 
Fecha de Ingreso: mayo-2004
Ubicación: -34.637167,-58.462984
Mensajes: 5.148
Antigüedad: 20 años, 5 meses
Puntos: 834
Respuesta: Eliminar script y vaciar memoria utilizada por este

Hombre, a veces hay que abandonar unos segundos la teoría y ponerse a testear:
Código PHP:
<?php 
if(isset($_GET['pp'])){
header("Content-type:text/css");
echo 
'
body{ background:#CCC;}
.pp{background:red;color:white;}
'
;
exit;
}
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Documento sin título</title>
<script type="text/javascript">
function loadCss(css) { 
    if(document.getElementById('estilos')) 
        document.getElementsByTagName('head')[0].removeChild(document.getElementById('estilos')); 
        var x = document.createElement("link"); 
        x.rel="stylesheet"; 
        x.href=css; 
        x.id="estilos"; 
       document.getElementsByTagName('head')[0].appendChild(x);     

function agregarElementoconClasePP(){
        var pp=document.createElement('div');
        pp.className='pp';
        pp.innerHTML='hola';
        document.body.appendChild(pp);
}
function removeCss(){
    if(document.getElementById('estilos')) 
        document.getElementsByTagName('head')[0].removeChild(document.getElementById('estilos'));
}
</script>

</head>

<body>
<form id="form1" name="form1" method="post" action="">
    <input onclick="loadCss('?pp')" type="button" name="button" id="button" value="cargar hoja de estilo" />
    <input onclick="removeCss()" type="button" name="button2" id="button2" value="borrar hoja de estilo" />
    <input onclick="agregarElementoconClasePP()" type="button" name="button3" id="button3" value="agregar elemento con clase pp" />
</form>
</body>
</html>
  #18 (permalink)  
Antiguo 06/09/2011, 15:38
Avatar de zerokilled
Javascripter
 
Fecha de Ingreso: abril-2009
Ubicación: Isla del Encanto, La Borinqueña [+>==]
Mensajes: 8.050
Antigüedad: 15 años, 7 meses
Puntos: 1485
Respuesta: Eliminar script y vaciar memoria utilizada por este

supongo que con eliminar del documento el elemento link/style es suficiente. o en su defecto cambiar la url de <link> para cargar el estilo apropiado para la sección. pues, cuando ocurre una de estas dos cosas, el navegador desecha los estilos. yo lo que haría es mantener dos <link>: uno para los estilos generales que aplique para toda las secciones, y el otro para secciones específicas. entonces, en cada cambio de sección modificas la url del <link> designado para las secciones individuales.
__________________
la maldad es una virtud humana,
y la espiritualidad es la lucha del hombre contra su maldad.
  #19 (permalink)  
Antiguo 06/09/2011, 15:53
de-troit
Invitado
 
Mensajes: n/a
Puntos:
Respuesta: Eliminar script y vaciar memoria utilizada por este

Yo la verdad aún no he probado eliminando el tag y corroborando luego si se libera la memoria de la hoja de estilo, sólo hice este experimento con un script JS y al parecer seguía en la memoria porque las funciones me seguían andando.

Zerokilled, estás seguro que con los estilos css basta con eliminar el tag? Si sé que es lo que dijiste, pero me gustaría que me reafirmaras para asegurarme :P, de todas maneras haré la prueba luego.

Según el código que puso Panimo5001 para remover el css obtiene el objeto head y remueve el tag del css importado, cada vez me convenzo más antes de hacer la prueba de que eso bastaría.

Saludos y gracias por su ayuda :)
  #20 (permalink)  
Antiguo 06/09/2011, 17:12
Avatar de Panino5001
Me alejo de Omelas
 
Fecha de Ingreso: mayo-2004
Ubicación: -34.637167,-58.462984
Mensajes: 5.148
Antigüedad: 20 años, 5 meses
Puntos: 834
Respuesta: Eliminar script y vaciar memoria utilizada por este

Con esto (mínimas modificaciones al otro ejemplo), podrás comprobar la certeza de la afirmación del amigo zerokilled ():
Código PHP:
<?php 
if(isset($_GET['pp'])){
header("Content-type:text/css");
echo 
'
body{ background:rgb('
.rand(0,255).','.rand(0,255).','.rand(0,255).');}
.pp{background:rgb('
.rand(0,255).','.rand(0,255).','.rand(0,255).');color:rgb('.rand(0,255).','.rand(0,255).','.rand(0,255).');}
'
;
exit;
}
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Documento sin título</title>
<script type="text/javascript">
function loadCss(css) { 
    if(document.getElementById('estilos')) 
        document.getElementsByTagName('head')[0].removeChild(document.getElementById('estilos')); 
        var x = document.createElement("link"); 
        x.rel="stylesheet"; 
        x.href=css; 
        x.id="estilos"; 
       document.getElementsByTagName('head')[0].appendChild(x);     

function agregarElementoconClasePP(){
        var pp=document.createElement('div');
        pp.className='pp';
        pp.innerHTML='hola';
        document.body.appendChild(pp);
}
function removeCss(){
    if(document.getElementById('estilos')) 
        document.getElementsByTagName('head')[0].removeChild(document.getElementById('estilos'));
}
</script>

</head>

<body>
<form id="form1" name="form1" method="post" action="">
    <input onclick="loadCss('?pp&'+(+new Date))" type="button" name="button" id="button" value="cargar hoja de estilo" />
    <input onclick="removeCss()" type="button" name="button2" id="button2" value="borrar hoja de estilo" />
    <input onclick="agregarElementoconClasePP()" type="button" name="button3" id="button3" value="agregar elemento con clase pp" />
</form>
</body>
</html>
  #21 (permalink)  
Antiguo 07/09/2011, 15:45
de-troit
Invitado
 
Mensajes: n/a
Puntos:
Respuesta: Eliminar script y vaciar memoria utilizada por este

Muchas gracias a todos por su ayuda, hice la prueba y funciona perfectamente ;)
Gracias amigos, ahora estoy arreglando otras cosas del plugin, cuando lo termine lo posteo para que lo vean, no soy bueno programando pero lo trataré de hacer lo mejor posible.

Saludos!

Etiquetas: js, memoria
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 18:34.