почему этот вызов jQuery .animate такой медленный? - PullRequest
1 голос
/ 26 ноября 2009

Привет всем, у меня есть довольно прямолинейная функция

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');
    }

Анимация сама по себе, изменение непрозрачности, очень быстрая, но есть некоторая задержка в ее вызове. console.time () сообщает о времени 2540MS и более. Я думаю, это может быть потому, что модуль div # анимируется вместе со своими детьми? но это не имеет смысла, потому что у меня есть другая функция «disableModule», которая делает то же самое в обратном порядке и работает с разумной скоростью.

Вот функция отключения модуля, значительно более продолжительная, но возвращает время около 242 мс

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');});
            }
          });
      });
    }

Ответы [ 2 ]

3 голосов
/ 28 ноября 2009

После некоторого трудного устранения неполадок я обнаружил, что это проблема с циклом обнаружения браузера в методе отключения:

  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');});
      }
    });

Комментирование этого блока привело к ускорению. Я чуть не вырвал свои волосы после попытки оптимизировать все остальное.

1 голос
/ 26 ноября 2009

Вы пробовали просто переупорядочить их?

module.find('.disabled_sheild').remove();
module.removeClass('disabled');
module.animate({'opacity' : '1.0'}, 300, function(){console.timeEnd('animate');});

Анимация происходит асинхронно, а методы find и remove могут потреблять ресурсы (тем более что find обходит дерево DOM), которые в противном случае могли бы использоваться для анимации.

Кроме того, поскольку вы динамически создаете «отключенный щит» в методе disable, вы можете сохранить его на

.
module.data("disabledShield", module.prepend('<div class="disabled_sheild"></div>'));

и просто используйте эту ссылку в вашем enable методе, чтобы избежать обхода DOM

module.data("disabledShield").remove();
module.removeClass('disabled');
module.animate({'opacity' : '1.0'}, 300, function(){console.timeEnd('animate');});

(см. http://docs.jquery.com/Internals/jQuery.data для документации по $.data)

...