javascript - horizontal - menu jquery vertical
¿Cómo puedo controlar las fugas de memoria de IE6+jQuery+jQuery-ui? (9)
¿Puedes probar esta demostración here ? Utiliza el mismo método que Dojo implementa para eliminar elementos de la dom. Algunas pruebas rápidas parecen aliviar las fugas, no del todo, pero mucho mejor.
ACTUALIZACIÓN Después de pasar un poco de tiempo en esto, estoy convencido de que no tiene nada que ver con el datepicker en sí.
Mis pruebas muestran que al volver a cargar una página falsa cada 1 segundo ve, por ejemplo, una fuga de memoria. Si luego incluye jquery en esta página, las filtraciones aumentan ligeramente (gastos generales de análisis del script) Si luego agrega jquery-ui a la mezcla, entonces nuevamente hay un ligero aumento en la pérdida de memoria.
Para probar esto, si evitas volver a cargar la página y, en su lugar, tienes un botón que solo agrega una entrada, crea el marcador de fecha y luego lo elimina, se observan muy pocas fugas si es que hay alguna.
Aquí hay una página de muestra con un par de citadores. Aquí está el resultado del goteo para eso:
texto alternativo http://www.picvault.info/images/537090308_omoya.png
Esta página se filtra indefinidamente en IE6sp1 cuando hago clic repetidamente en el botón Actualizar (IE6sp3 +, Opera 9, Chrome2 y FF3 + parecen estar bien). La memoria aumenta y nunca baja hasta que cierro el navegador por completo.
También intenté utilizar la última versión nocturna de jquery (r6414) y la última interfaz de usuario estable (1.7.2), pero no hizo ninguna diferencia. He intentado varias cosas sin éxito ( CollectGarbage , AntiLeak , otros).
Estoy buscando una solución que no sea "¡utilice un navegador diferente! 1" ya que no tengo ningún control sobre eso. ¡Cualquier ayuda será apreciada!
Actualización 1: agregué ese evento de botón a un bucle y esto es lo que sucede (la caída repentina es cuando termino el IE):
Actualización 2: archivé un informe de error (dedos cruzados).
Actualización 3: esto también está en la lista de correo .
Actualización 4: Esto (como se informa en la lista de correo) no funciona, y de hecho empeora las cosas:
$(window).bind("unload", function() {
$(''.hasDatepicker'').datepicker(''destroy'');
$(window).unbind();
});
No es suficiente llamar simplemente destruir. Todavía estoy varado con esto y estoy muy cerca de arrancarle el proyecto a jquery. Me encanta (¡realmente lo creo!) Pero si está roto, no puedo usarlo.
Actualización 5: ¡ Comenzando la recompensa, otros 550 puntos a una persona útil!
Actualización 6: algunas pruebas más han demostrado que esta filtración existe en IE6 e IE6sp1, pero se ha corregido en IE6sp2 +. Ahora, sobre las respuestas que tengo hasta ahora ...
Hasta ahora, todas las respuestas han sido alguna de estas:
- Abandone los usuarios de IE6sp0 / sp1 o ignórelos
- Depurar jquery y solucionar el problema yo mismo
- No puedo reproducir el problema.
Sé que los mendigos no pueden ser selectivos, pero esos simplemente no son respuestas a mi problema.
No puedo abandonar a mis usuarios. Constituyen el 25% de la base de usuarios. Esta es una aplicación personalizada escrita para un cliente, diseñada para funcionar en IE6. No es una opción abandonar IE6sp0 / sp1. No es una opción decirle a mis clientes que solo se ocupen de eso. Se filtra tan rápido que después de cinco minutos, algunas de las máquinas más débiles son inutilizables.
Además, aunque me gustaría convertirme en un ninja JS, así puedo buscar fugas de memoria poco claras en el código jquery (siempre que esto sea culpa de MS, no de Jquery), tampoco veo que eso suceda.
Finalmente, varias personas han reproducido el problema aquí y en la lista de correo. Si no puede reproducirlo, puede tener IE6SP2 +, o puede que no sea lo suficientemente refrescante.
Obviamente, este tema es muy importante para mí (de ahí las 6 revisiones, recompensas, etc.) por lo que estoy abierto a nuevas ideas, pero tenga en cuenta que ninguna de esas tres sugerencias funcionará para mí.
Gracias a todos por su consideración y comprensión. Por favor, sigan viniendo!
Actualización 7: La recompensa ha terminado y la respuesta de Keith fue aceptada por SO. Lamento que solo se hayan otorgado la mitad de los puntos (ya que no seleccioné la respuesta por mi cuenta), pero sigo realmente atascado, así que creo que la mitad es justa.
Tengo la esperanza de que el equipo de jquery / jquery-ui pueda solucionar este problema, pero me temo que tendré que escribir esto como "imposible (por ahora)" y dejar de usar algunos o todos los jquery. Gracias a todos por su ayuda y consideración. Si alguien viene con una solución real a mi problema, publíquelo y encontraré la forma de recompensarlo.
Eche un vistazo a este fragmento que limpia los nodos DOM. Lo podrías encontrar útil. https://.com/a/9519996/139667
El mejor depurador disponible para IE6 es Visual Studio. (Incluso la edición gratuita funcionará). Como menciona Janie, si su problema solo ocurre en IE6, querrá depurar en IE6, prestando especial atención al código que solo se ejecuta allí.
El problema aquí es un poco más profundo que ''solo'' jquery. Jquery junto con muchos otros navegadores "filtran" referencias circulares entre objetos DOM y receptores de objetos. Digamos que tiene un campo de entrada que tiene conectado un oyente, luego elimina el elemento del dom y no tiene ninguna referencia al oyente en su código. Ahora cualquier navegador moderno (> = ie7, ff, chrome, safari, opera) vivirá con eso y la basura lo recogerá, mientras que IE6 pensará que debido a que hay un oyente conectado a un elemento dom no debería recoger el dom y el oyente en sí.
Para evitarlo, algunas personas usan patrones de diseño muy complicados como se destaca, por ejemplo, en el código de eventos en Google Doctype. Para solucionar el problema de IE6, realmente necesitaría reescribir una parte de jquery para solucionar el problema de IE6 y / o cambiar a usar una biblioteca diferente y / o no adjuntar ningún detector de eventos en su aplicación a los eventos de DOM.
El problema con IE 6 es que tiene dos recolectores de basura. Uno para JavaScript y otro para el DOM. Entonces, por ejemplo, si adjuntas una función a un evento DOM y luego borras el elemento DOM, la función seguirá existiendo en la memoria.
Mira esta presentación de diapositivas . Es un poco irónico, pero es una buena información.
Solucionaron este problema en IE 7. Probé tu página en IE8 en Windows 7 y no veo una pérdida de memoria.
Es obvio que los problemas que ha estado describiendo surgen de un error en IE6 que no puede subvertir con una corrección de software (ya sea una actualización de jQuery, una llamada manual a CollectGarbage, o algún otro hack de JavaScript / DOM).
Hay 3 opciones, en mi opinión, que solucionarían este problema.
Me imagino que sus clientes / usuarios están utilizando IE6 SP0 debido a algún estándar o regulación de la compañía, o incluso porque alguna aplicación web anterior que todavía usan no es compatible con los navegadores más nuevos. Si no es una opción actualizar a IE7 (o, por lo tanto, IE8), puede ponerse en contacto con el departamento de TI de sus clientes y señalar educadamente que actualizar IE6 con los últimos service packs no solo solucionaría un problema con una aplicación que son pagando, pero también parche muchos defectos de seguridad y rendimiento que sin duda existen en IE6 SP0. Es cierto que esa podría no ser una situación cómoda, pero podría resolver los problemas que se encuentran, al mismo tiempo que les permite trabajar con un navegador que lo requiera por cualquier motivo.
Si puede convencer al departamento de TI de sus clientes de que IE6 es anticuado, es posible que estén dispuestos a permitir que sus usuarios actualicen a un navegador más nuevo. No es exagerado decir que alguien que dirija un departamento de TI estaría más dispuesto a forzar a los empleados a actualizar una pieza de software si supieran que: a) está plagada de fallas y agujeros de seguridad, o b) se aproxima a su fin de la fecha de soporte (como IE6 SP0 es). IE6 SP0 en XP Pro SP2 es compatible hasta el 13 de julio de 2010, por lo que todavía tiene algo de tiempo, pero al señalarlo, junto con otros defectos / limitaciones que podría encontrar, es posible que piense seriamente en actualizar más pronto que tarde.
Si no puede convencer a nadie para que actualice sus navegadores a IE6 SPX, o a IE7 / 8, entonces no sé si tiene otra opción más que eliminar el control ofensivo de su página, y buscar una opción diferente hasta que el el navegador del usuario lo permite. Seguramente hay muchas implementaciones de control de selector de fecha disponibles en línea que se adaptarán a sus necesidades. Puede que no sea tan elegante como la versión de jQuery, pero no tiene muchas otras opciones en este momento.
¡Espero que encuentres una solución!
Este problema está en una parte solo de IE6 de jQuery, o en una parte general de jQuery que carece de código específico de IE6 (como se indica en los comentarios). De cualquier manera, sigue siendo un error en jQuery que necesita abordarse. about: blank Tendrás que excavar en jQuery o presentar un ticket de error . Si logras arreglarlo, no te olvides de adjuntar un diff al bugtracker, para que el proyecto mejore un poco. ;)
Si tengo algo de tiempo libre, trataré de ayudarte con esto.
Editar
Ok, entonces el problema parece insuperable.
La fuga a la que se enfrenta es un problema exclusivo de IE 6 SP 0, una fuga causada por el enfoque de IE hacia DOM. No importa qué marco JS use, se niega a funcionar correctamente.
Entonces, tus opciones actuales son:
- Morir intentando que tus usuarios actualicen IE 6 a una versión más nueva / Service Pack,
- Muere (como en una fuga) en IE (perdiendo clientes) o
- Morir tratando de trabajar en IE.
Pero eso no necesariamente significa que no puedes resolver esto. ¿Qué tal si tratamos de dejar de lado lo de lana?
Muestre a cada usuario que no sea de IE 6 SP 0 el selector de fecha de jQuery, y solo IE 6 SP 0 a otro de fecha más flexible (y probablemente básico) con los comentarios condicionales de IE. De esta forma, puede mantener la funcionalidad y / o funcionalidad de su software y permitir que los usuarios de IE 6 tengan la misma funcionalidad básica.
Puede que no sea una opción tan clara, pero aún así podrás usar lo que quieras, y IE6 aún podrá funcionar sin fugas.
El único problema será que tendrás una carga más grande al tener que eliminar dos marcadores de fecha distintos. Pero tendrá que depurar IE 6 de todos modos, por lo que puede ser su mejor apuesta en este momento.
Odio decir esto, tu enfoque es correcto y profesional, pero estaría tentado de dejarlo.
Las consecuencias de no solucionar esto es que los usuarios de IE6 notarán que su máquina se vuelve cada vez más lenta y, o bien se bloquea por completo o es más probable que se cuelgue IE6.
¿Y qué?
Realmente, ¿por qué es este tu problema?
El suyo definitivamente no será el único sitio que visiten con esta fuga, y verán IE6 fallar regularmente independientemente de lo que haga, porque eso es lo que hace.
Es poco probable que alguien aún en IE6 pueda señalar su aplicación como una que se filtra.
Finalmente, cuando IE6 se cuelga, informa IE6 como el culpable - legítimamente puede señalar que se trata de un error en IE6 que Microsoft ha corregido en una nueva versión.
Su tiempo costoso se emplea mejor para mejorar la aplicación para los usuarios que no están atrapados en un infierno heredado: su aplicación debería funcionar básicamente para usuarios de IE6, pero este tipo de problema puede absorber todo su tiempo y no solucionar su problema. IE6 seguirá siendo un agujero de seguridad no soportado, colmado de errores de un navegador.
Sospecho que los desarrolladores de jQuery tienen una visión similar a la mía. También tienes que hacer algunas cosas realmente feas para solucionar este error en IE6, incluido el trabajo DOM malicioso que detiene la fuga pero en realidad es mucho más lento.
Actualizar
Bien, este no es un problema fácil de corregir: MS describe el error IE6 (y proporciona consejos sobre cómo solucionarlo) aquí: http://msdn.microsoft.com/en-us/library/bb250448(VS.85).aspx
Básicamente, esto no es un problema con javascript o jQuery - el problema real es con el DOM IE6 - cuando los elementos HTML se agregan a la página (por javascript, en lugar de estar en la página cuando se carga) IE no puede recogerlos a menos que sean creados de una manera muy específica.
Esto se ve al revés de cómo jQuery UI crea elementos (vea el error de orden de inserción de DOM en el enlace anterior) y esto no es algo que los desarrolladores de jQuery puedan arreglar fácilmente.
Entonces, ¿cómo arreglas el problema? Bueno, puedes quedarte con el calendario emergente heredado para IE6 o puedes escribir el tuyo propio.
Yo recomendaría lo primero, pero si realmente quiere construir lo último, hay algunas reglas básicas a seguir:
Siempre agregue elementos de arriba hacia abajo; por ejemplo, si desea construir una tabla, agregue el elemento
<table>
en el DOM de la página, luego agregue<tr>
luego<td>
y así sucesivamente. Esto es de vuelta al frente, ya que es mucho más rápido construir toda la tabla y luego agregarlo al DOM - desafortunadamente, IE6 lo pierde.Solo use los atributos CSS y HTML 3.2. Suena tonto, pero IE6 crea objetos adicionales para almacenar los atributos adicionales (o propiedades ''expando'') y estos también tienen fugas.
Algo relacionado con (2), pero como @gradbot menciona IE6 tiene problemas con la recolección de variables de javascript: si hacen referencia a un elemento DOM dentro de un evento disparado desde ese elemento, puede tener problemas. Esto también se ve agravado por las referencias javascript a los elementos DOM que tienen propiedades ''expando''.
Si echas un vistazo en línea, es posible que ya haya un calendario DHTML desplegable que cumpla con estas reglas: no será tan bonito, rápido ni configurable como el jQuery UI, pero estoy seguro de que lo he visto hecho sin fugas en IE6.
Creo que la mejor opción es mantener la mayor cantidad de estática posible, por ejemplo, puede cargar la cuadrícula del calendario (números de semana y encabezados de columna del día) con la página y luego cargar dinámicamente los números (y nada más). Cree los números del día como enlaces, con javascript en el href: no es una buena práctica normalmente, pero es menos probable que se filtre en IE6.
intente eliminar estos objetos después de destruir el objeto datepicker:
$.datepicker = null;
$.fn.datepicker = null;