Подтвердить что ты не робот

JQuery animate() и производительность браузера

У меня есть некоторые элементы, которые я перемещаю по странице очень медленно. По сути, я уменьшаю левый край двух изображений в течение 40 секунд или около того.

Визуально, он прекрасно работает. Тем не менее, мой процессор скапливается до 50% использования во время анимации. Это не относится ни к одному браузеру, ни к одному браузеру Safari3 и Firefox3. Если у меня есть оба браузера, которые запускают страницу, мой процессор кричит примерно на 95%.

Я использую jQuery 1.3. Обе анимации происходят одновременно. На странице нет Flash. Если я прокомментирую код (удаляю анимацию) и обновляю страницу, мой процессор сразу же возвращается к нормальному использованию.

Я надеюсь, что мне не нужно прибегать к Flash, но даже просмотр шоу на Hulu.com не скапливает мой процессор так.

Мысли?

4b9b3361

Ответ 1

Я думаю, что способ jQuery animate() заключается в том, что он использует таймер, который периодически запускает и вызывает функцию, которая обновляет DOM, чтобы отразить состояние анимации. Обычно анимации относительно короткие, и они могут покрывать довольно много экранной недвижимости, поэтому я подозреваю (без подтверждения), что таймер истекает, и reset, с довольно высокой скоростью, чтобы генерировать гладкую анимацию. Поскольку ваша анимация занимает много времени, вы можете изменить функцию анимации так, чтобы скорость, с которой происходит анимация, может быть установлена ​​с помощью опции. В вашем случае вам нужно будет обновлять каждые 250 мс или около того, так как вы покрываете примерно 3-4 пикселя в секунду, примерно.

Ответ 2

Я знаю, что это старый вопрос, и Тим предоставил отличный ответ, но я просто подумал, что должен опубликовать обновление для тех, кто ищет решение этой проблемы, так как теперь есть более простой способ...

Как и в jQuery 1.4.3, вы можете установить интервал jQuery animate, используя напрямую jQuery.fx.interval. Поэтому вы можете просто сделать что-то вроде:

jQuery.fx.interval = 50;

Ответ 3

Люди упомянули о замедлении частоты обновления jQuery. Вы можете переопределить функцию таймера в jQuery 1.4 с этим файлом (jquery.animation-fix.js):

function now() {
    return (new Date).getTime();
}
jQuery.fx.prototype.custom = function( from, to, unit ) {
    this.startTime = now();
    this.start = from;
    this.end = to;
    this.unit = unit || this.unit || "px";
    this.now = this.start;
    this.pos = this.state = 0;

    var self = this;
    function t( gotoEnd ) {
        return self.step(gotoEnd);
    }

    t.elem = this.elem;

    if ( t() && jQuery.timers.push(t) && !jQuery.fx.prototype.timerId ) {
        //timerId = setInterval(jQuery.fx.tick, 13);
        jQuery.fx.prototype.timerId = setInterval(jQuery.fx.tick, 2050);
    }
}

Так измените строку с этим в ней

jQuery.fx.prototype.timerId = setInterval(jQuery.fx.tick, 50);

Измените 50 на любой желаемый интервал. То есть в Miliseconds (ms)

Если вы сохраните этот код в другом файле, вы можете прикрепить его следующим образом:

<script src="/js/jquery-1.4.2.min.js" type="text/javascript"></script>
<script src="/js/jquery.animation-fix.js" type="text/javascript"></script>

Ответ 4

jQuery animate использует функцию javascript 'setInterval' для обновления объектов каждые несколько миллисекунд. К сожалению, интервал в jQuery по умолчанию равен 13 мс. Thats 76 обновлений каждую секунду. Способ многого для таких медленных и средних анимаций.

13 мс жестко закодированы в jQuery. Таким образом, вы можете напрямую изменить это значение только в jQuery.js. Если у вас есть только медленные clowds, вы можете подняться до 100 мс. Если у вас есть более быстрая анимация, вы должны установить ее на 50.

Вы можете изменить параметр для setInterval(); в функции custom. 'jQuery.fx.prototype {... custom: function() {...}...}'

Ответ 5

Анимации включают в себя операции циклирования, и они действительно будут критиковать CPU независимо от того, что.

Я не знаю, как легко это сделать с jQuery, но что должно произойти, анимация должна потреблять меньше циклов. Либо вы делаете ani немного более зубчатым (дисплей не такой плавный), цикл должен быть оптимизирован или уменьшить работу ani.

40 секунд? разве это немного длиннее для анимации? Я думал, что они будут немного более быстрыми, чем это.

Ответ 6

Я просто смотрел производительность анимации под Scriptaculous и нашел похожие всплески процессора: примерно 50% для IE, чуть более высокая производительность (16-30%) для Firefox - как на ПК DuoCore. Поскольку JQuery и Scriptaculous работают, изменяя базовый CSS, я думаю, что можно с уверенностью сказать, что любая реализация Javascript будет стоить дорого.

Возможно, вы все равно столкнетесь с Flash.

Ответ 7

Мне очень нравится ответ, отправленный Тимом, хотя мне нужно было заставить это исправление работать в рабочей среде Drupal 6.

У меня установлен jQuery 1.3.2 с использованием модуля обновления jQuery, поэтому есть несколько различий между тем, что я использую, и jQuery 1.4, для которого исправлено задание Tim.

Следуя инструкциям Тима, я получил 90% от того, как это сделать, мне просто нужно было положить мой мыслящий колпачок на 10 минут, чтобы придумать этот код вместо этого.

значения таймера от 25 до 33, похоже, работают намного лучше, чем 13 мс для анимаций средней скорости, таких как замирание фоновых изображений.

var timerId;

function now() {
    return (new Date).getTime();
}

jQuery.fx.prototype.custom = function( from, to, unit ) {
    this.startTime = now();
    this.start = from;
    this.end = to;
    this.unit = unit || this.unit || "px";
    this.now = this.start;
    this.pos = this.state = 0;

    var self = this;
    function t( gotoEnd ) {
        return self.step(gotoEnd);
    }

    t.elem = this.elem;

        if ( t() && jQuery.timers.push(t) && !timerId ) {
    timerId = setInterval(function(){
        var timers = jQuery.timers;

        for ( var i = 0; i < timers.length; i++ )
            if ( !timers[i]() )
                timers.splice(i--, 1);

        if ( !timers.length ) {
            clearInterval( timerId );
            timerId = undefined;
        }
    }, 25);
}
};