28 votes

Comment puis-je contrôler les fuites de mémoire d'IE6+jQuery+jQuery-ui ?

Voici un page des échantillons avec un couple de cueilleurs de dattes. Voici le résultat de Drip pour ça :

alt text

Cette page fuit indéfiniment dans IE6sp1 lorsque je clique sur le bouton Rafraîchir à plusieurs reprises (IE6sp3+, Opera 9, Chrome2, et FF3+ semblent être bons). La mémoire augmente et ne diminue jamais jusqu'à ce que je ferme complètement le navigateur.

J'ai également essayé d'utiliser la dernière version nocturne de jquery (r6414) et la dernière version stable de l'interface utilisateur (1.7.2) mais cela n'a fait aucune différence. J'ai essayé plusieurs choses sans succès ( CollectGarbage , AntiLeak et autres).

Je cherche une solution autre que "utilisez un autre navigateur!1", car je n'ai aucun contrôle là-dessus. Toute aide sera grandement appréciée !

Mise à jour 1 : J'ai ajouté l'événement de ce bouton à une boucle et voici ce qui se passe (la chute soudaine se produit lorsque je ferme IE) : alt text

Mise à jour 2 : J'ai déposé une rapport de bogue (croisons les doigts).

Mise à jour 3 : C'est aussi sur le liste de diffusion .

Mise à jour 4 : Ceci (comme signalé sur la liste de diffusion) ne fonctionne pas, et en fait aggrave les choses :

$(window).bind("unload", function() {
  $('.hasDatepicker').datepicker('destroy');
  $(window).unbind();
});

Il ne suffit pas d'appeler détruire. Je suis toujours bloqué sur ce point et je suis sur le point de retirer jquery du projet. Je l'adore (vraiment !) mais s'il est cassé, je ne peux pas l'utiliser.

Mise à jour 5 : En commençant la prime, un autre 550 points à une personne utile !

Mise à jour 6 : Des tests supplémentaires ont montré que cette fuite existe dans IE6 et IE6sp1, mais a été corrigée dans IE6sp2+. Maintenant, à propos des réponses que j'ai jusqu'à présent...

Jusqu'à présent, toutes les réponses ont été l'une d'entre elles :

  1. Abandonner les utilisateurs d'IE6sp0/sp1 ou les ignorer ou les ignorer
  2. Déboguer jquery et résoudre le problème moi-même
  3. Je ne peux pas reproduire le problème.

Je sais que les mendiants ne peuvent pas faire le difficile, mais ce ne sont tout simplement pas des réponses à mon problème.

Je ne peux pas abandonner mes utilisateurs. Ils représentent 25% de la base d'utilisateurs. C'est une application personnalisée écrite pour un client, conçue pour fonctionner sur IE6. Il n'est pas question d'abandonner IE6sp0/sp1. Je ne peux pas dire à mes clients de faire avec. Il fuit si vite qu'après cinq minutes, certaines des machines les plus faibles sont inutilisables.

De plus, même si j'aimerais devenir un ninja du JS pour pouvoir traquer les obscures fuites de mémoire dans le code de jquery (il est vrai que c'est la faute de MS, pas de jquery), je ne vois pas cela arriver non plus.

Enfin, plusieurs personnes ont reproduit le problème ici et sur la liste de diffusion. Si vous ne pouvez pas le reproduire, il se peut que vous ayez IE6SP2+, ou que vous ne rafraîchissiez pas assez.

Il est évident que cette question est très importante pour moi (d'où les 6 révisions, la prime, etc.) et je suis donc ouvert à de nouvelles idées, mais gardez à l'esprit qu'aucune de ces trois suggestions ne me conviendra.

Merci à tous pour votre réflexion et vos idées. Continuez à nous en faire part !

Mise à jour 7 : Le bounty a pris fin et la réponse de Keith a été acceptée automatiquement par l'OS. Je suis désolé que seulement la moitié des points aient été attribués (puisque je n'ai pas choisi la réponse moi-même), mais je suis toujours très bloqué et je pense que la moitié est juste.

J'espère que l'équipe jquery/jquery-ui pourra résoudre ce problème, mais j'ai peur de devoir le considérer comme "impossible (pour l'instant)" et d'arrêter d'utiliser tout ou partie de jquery. Merci à tous pour votre aide et votre considération. Si quelqu'un trouve une vraie solution à mon problème, merci de le poster et je trouverai un moyen de le récompenser.

21voto

Keith Points 46288

Je déteste dire ça, votre approche est correcte et professionnelle, mais je serais tenté de laisser tomber.

Si ce problème n'est pas résolu, les utilisateurs d'IE6 verront leur machine devenir de plus en plus lente et finir par se bloquer complètement ou, plus probablement, par bloquer IE6.

Et alors ?

Vraiment - pourquoi est-ce votre problème ?

Votre site ne sera certainement pas le seul qu'ils visiteront avec cette fuite, et ils verront IE6 planter régulièrement, quoi que vous fassiez, car c'est ce qu'il fait.

Il est peu probable que quelqu'un qui utilise encore IE6 puisse signaler que votre application présente des fuites.

Enfin, lorsque IE6 se bloque, il signale qu'il est le coupable - vous pouvez légitimement signaler qu'il s'agit d'un bogue dans IE6 que Microsoft a corrigé dans une nouvelle version.

Votre temps coûteux est mieux utilisé à améliorer l'application pour les utilisateurs qui ne sont pas piégés dans l'enfer de l'héritage - votre application devrait fondamentalement fonctionner pour les utilisateurs d'IE6, mais ce genre de problème peut vous faire perdre tout votre temps et ne pas résoudre leur problème. IE6 restera un navigateur non pris en charge, sujet à des pannes et à des failles de sécurité.

Je soupçonne les développeurs de jQuery d'être du même avis que moi. De plus, il faut faire des choses vraiment moches pour contourner ce bogue dans IE6, y compris des travaux DOM qui arrêtent la fuite mais sont en fait beaucoup plus lents.


Mise à jour

Ok, ce n'est pas un problème facile à résoudre - MS décrit le bogue d'IE6 (et fournit des conseils sur la façon de le résoudre) ici : http://msdn.microsoft.com/en-us/library/bb250448(VS.85).aspx

En fait, il ne s'agit pas d'un problème avec javascript ou jQuery, mais plutôt avec le DOM d'IE6. Lorsque des éléments HTML sont ajoutés à la page (par javascript, plutôt que d'être dans la page lorsqu'elle se charge), IE ne peut pas les récupérer, à moins qu'ils ne soient créés d'une manière très spécifique.

Il s'agit d'un problème inverse de la façon dont jQuery UI construit les éléments (voir le bogue de l'ordre d'insertion DOM dans le lien ci-dessus) et ce n'est donc pas quelque chose que les développeurs de jQuery ou vous pouvez facilement corriger.

Alors comment résoudre le problème ? Vous pouvez vous en tenir à l'ancien calendrier des fenêtres pop-up pour IE6 ou écrire votre propre calendrier.

Je vous recommande la première solution, mais si vous voulez vraiment construire la seconde, il y a quelques règles de base à suivre :

  1. Ajoutez toujours les éléments de haut en bas - par exemple, si vous voulez construire un tableau, ajoutez le champ <table> dans le DOM de la page, puis ajouter l'élément <tr> entonces <td> et ainsi de suite. Il s'agit d'un retour en arrière, car il est beaucoup plus rapide de construire la table entière et de l'ajouter ensuite au DOM - malheureusement, c'est là qu'IE6 en perd la trace.

  2. N'utilisez que les attributs CSS et HTML 3.2 - cela peut paraître idiot, mais IE6 crée des objets supplémentaires pour stocker les attributs supplémentaires (ou propriétés "expando") et ceux-ci fuient également.

  3. Un peu en rapport avec le point (2), mais comme @gradbot le mentionne, IE6 a des problèmes de collecte des variables javascript - si elles font référence à un élément DOM à l'intérieur d'un événement déclenché par cet élément, vous pouvez avoir des problèmes. Ce problème est également aggravé par les références javascript aux éléments DOM qui ont des propriétés 'expando'.

Si vous regardez sur Internet, il existe peut-être déjà un calendrier DHTML déroulant qui respecte ces règles - il ne sera pas aussi joli, rapide ou configurable que celui de jQuery UI, mais je suis sûr de l'avoir vu réalisé sans fuite dans IE6.

Je pense que le mieux est de garder le plus de choses statiques possible - par exemple, vous pourriez charger la grille du calendrier (numéros de semaine et en-têtes de colonne de jour) avec la page et ensuite charger dynamiquement les numéros (et rien d'autre). Créez les numéros des jours sous forme de liens, avec du javascript dans le href - ce n'est pas la meilleure pratique en général, mais il y a beaucoup moins de risques de fuite dans IE6.

4voto

Pwninstein Points 7293

Il est évident que les problèmes que vous avez décrits proviennent d'une faille dans IE6 que vous ne pouvez pas contourner avec un correctif logiciel (qu'il s'agisse d'une mise à jour de jQuery, d'un appel manuel à CollectGarbage ou d'un autre hack JavaScript/DOM).

Il y a 3 options, à mon sens, qui permettraient de résoudre ce problème.

  1. J'imagine que vos clients/utilisateurs utilisent IE6 SP0 en raison d'une norme ou d'un règlement de l'entreprise, ou même parce qu'une ancienne application web qu'ils utilisent encore ne prend pas en charge les navigateurs plus récents. S'il n'est pas possible de passer à IE7 (ou donc à IE8), vous pourriez prendre contact avec le service informatique de vos clients et leur faire poliment remarquer que la mise à jour d'IE6 avec les derniers Service Packs permettrait non seulement de résoudre un problème avec une application qu'ils paient, mais aussi de corriger de nombreuses failles de sécurité et de performance qui existent indubitablement dans IE6 SP0. Certes, ce n'est pas une situation confortable, mais cela pourrait résoudre les problèmes que vous rencontrez, tout en leur permettant de continuer à travailler avec un navigateur dont ils ont besoin pour une raison quelconque.

  2. Si vous parvenez à convaincre le service informatique de vos clients que IE6 est dépassé, il sera peut-être disposé à autoriser vos utilisateurs à passer à un navigateur plus récent. Il n'est pas exagéré de dire que les responsables d'un service informatique seraient plus enclins à obliger leurs employés à mettre à niveau un logiciel s'ils savaient qu'il est soit a) truffé de défauts et de failles de sécurité, soit b) proche de sa date de fin de support (comme IE6 SP0). IE6 SP0 sur XP Pro SP2 est pris en charge jusqu'au 13 juillet 2010 - il a donc encore un peu de temps, mais le fait de le signaler, ainsi que d'autres failles/limitations que vous pourriez trouver, pourrait les faire réfléchir sérieusement à une mise à niveau plus tôt que prévu.

  3. Si vous ne parvenez pas à convaincre les utilisateurs de mettre à jour leur navigateur vers IE6 SPX ou IE7/8, je ne sais pas si vous avez d'autre choix que de supprimer le contrôle incriminé de votre page et de choisir une autre option jusqu'à ce que le navigateur de l'utilisateur le permette. Il existe certainement de nombreuses implémentations d'un contrôle de sélection de date disponibles en ligne qui pourraient répondre à vos besoins. Elle ne sera peut-être pas aussi élégante que la version jQuery, mais vous n'avez pas beaucoup d'autres options à ce stade.

J'espère que vous trouverez une solution !

2voto

voyager Points 17283

Ce problème se situe soit dans une partie de jQuery réservée à IE6, soit dans une partie générale de jQuery qui ne comporte pas de code spécifique à IE6 (comme indiqué dans les commentaires). Quoi qu'il en soit, il s'agit toujours d'un bogue dans jQuery qui doit être résolu. about:blank Vous devrez soit se plonger dans jQuery o déposer un ticket de bogue . Si vous parvenez à le corriger, n'oubliez pas de joindre un diff au bugtracker, afin que le projet s'améliore un peu ;)

Si j'ai un peu de temps libre, j'essaierai de vous aider.

Modifier

Ok, donc le problème semble insurmontable.

La fuite que vous rencontrez est un problème propre à IE 6 SP 0, une fuite causée par l'approche d'IE concernant le DOM. Peu importe le framework JS que vous utilisez, il refuse de fonctionner correctement.

Donc, vos options actuelles sont :

  • Meurs en essayant pour que vos utilisateurs mettent à jour IE 6 vers une version plus récente/un Service Pack,
  • mourir (comme dans fuite) dans IE (perte de clients) ou
  • mourir en essayant de travailler sur IE.

Mais ça ne veut pas nécessairement dire que vous ne pouvez pas vous en sortir. Et si tu essayais juste de passer outre le truc du monde ?

Montrer à tous les utilisateurs qui ne sont pas sous IE 6 SP 0 l'indicateur de date jQuery, et seulement à IE 6 SP 0 un autre indicateur de date plus résistant (et probablement basique) avec l'indicateur de date d'IE. commentaires conditionnels . De cette façon, vous pouvez conserver la beauté/fonctionnalité de votre logiciel et permettre aux utilisateurs d'IE 6 de bénéficier de la même fonctionnalité de base.

Ce n'est peut-être pas une option aussi propre, mais vous pourrez toujours utiliser ce que vous voulez, et IE6 pourra toujours fonctionner sans fuite.

El uniquement Le problème sera que vous aurez une charge plus importante, en devant dégager deux collecteurs de données distincts. Mais comme vous devrez de toute façon déboguer IE 6, c'est peut-être votre meilleure option pour le moment.

2voto

djspark Points 157

Essayez de supprimer ces objets après avoir détruit l'objet datepicker :

$.datepicker = null;
$.fn.datepicker = null;

1voto

gradbot Points 9219

Le problème avec IE 6 est qu'il a deux collecteurs de déchets. Un pour JavaScript et un pour le DOM. Ainsi, par exemple, si vous attachez une fonction à un événement DOM et que vous supprimez ensuite l'élément DOM, la fonction existera toujours en mémoire.

Regarde ça diaporama . Il s'agit d'un peu de langue de bois, mais c'est une bonne information.

Ils a réglé ce problème dans IE 7. J'ai essayé votre page dans IE8 sous Windows 7 et je ne vois pas de fuite de mémoire.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X