pourquoi cet appel .animate jQuery est-il si lent?
-
05-07-2019 - |
Question
Bonjour à tous, j’ai une fonction assez simple
enableModule : function(moduleName){
var module = $('div#'+moduleName);
console.log('enabling '+moduleName);
console.time('animate');
module.animate({'opacity' : '1.0'}, 300, function(){console.timeEnd('animate');});
module.find('.disabled_sheild').remove();
module.removeClass('disabled');
console.log('end of enable Module');
}
L’animation elle-même, le changement d’opacité, est très rapide, mais l’appel est retardé. console.time () signale des temps de 2540 MS et plus. Je pense que c'est peut-être parce que le module div # est animé avec ses enfants? mais ce dosage a du sens car j’ai une autre fonction " disableModule " qui fait la même chose en sens inverse et fonctionne à une vitesse raisonnable.
Voici la fonction de désactivation du module, qui est beaucoup plus longue mais qui renvoie des temps d’environ 242 ms
disableModule : function(moduleName){
$('div#'+moduleName+', div.'+moduleName).each(function(){
var module = $(this);
module.prepend('<div class="disabled_sheild"></div>');
var sheild = module.find('.disabled_sheild');
sheild.css({'position' : 'absolute', 'z-index' : '200'});
sheild.width(module.width());
sheild.height(module.height());
jQuery.each(jQuery.browser, function(i) {
if($.browser.msie){
//module.css("display","none");
//if using ie give sheild a transparent background layout
}else{
console.time('animate');
module.animate({'opacity' : '0.5'}, function(){ console.timeEnd('animate');});
}
});
});
}
La solution
Après des dépannages ardus, j'ai découvert qu'il s'agissait d'un problème lié à la boucle de détection du navigateur dans la méthode de désactivation:
jQuery.each(jQuery.browser, function(i) {
if($.browser.msie){
//module.css("display","none");
//if using ie give sheild a transparent background layout
}else{
console.time('animate');
module.animate({opacity : 0.5}, 200, function(){console.timeEnd('animate');});
}
});
Commenter ce blocage a tout mis en place. J'ai presque tiré les cheveux après avoir essayé d'optimiser tout le reste.
Autres conseils
Avez-vous essayé simplement de les ré-ordonner?
module.find('.disabled_sheild').remove();
module.removeClass('disabled');
module.animate({'opacity' : '1.0'}, 300, function(){console.timeEnd('animate');});
L’animation est asynchrone et les méthodes find
et remove
pourraient consommer des ressources (d’autant plus que find
parcourt l’arborescence DOM) qui pourraient autrement être utilisées. utilisé pour l'animation.
De plus, puisque vous créez de manière dynamique le "bouclier désactivé". dans la méthode disable
, vous pouvez l'enregistrer
module.data("disabledShield", module.prepend('<div class="disabled_sheild"></div>'));
et utilisez simplement cette référence dans votre méthode enable
pour éviter la visite DOM
module.data("disabledShield").remove();
module.removeClass('disabled');
module.animate({'opacity' : '1.0'}, 300, function(){console.timeEnd('animate');});
(Voir http://docs.jquery.com/Internals/jQuery.data pour la documentation sur $. data ??code>)