web-dev-qa-db-ja.com

jQuery animate()とブラウザのパフォーマンス

ページ上を非常にゆっくりと移動している要素がいくつかあります。基本的に、40秒程度のスパンで2つの画像の左マージンを減らしています。

視覚的には、美しく機能しています。 ただし、私のプロセッサはアニメーション中に約50%の使用率にジャンプします。これは単一のブラウザにも固有ではありません-Safari3とFirefox3でも同じです。両方のブラウザでページを実行している場合、CPUは約95%の使用率で叫んでいます。

私はjQuery1.3を使用しています。両方のアニメーションが同時に発生しています。ページにフラッシュはありません。コードをコメントアウトして(アニメーションを削除して)ページを更新すると、プロセッサはすぐに通常の使用法に戻ります。

Flashに頼る必要がないことを願っていますが、Hulu.comで番組を見ても、このようにCPUが急上昇することはありません。

考え?

35
Jeremy Ricketts

JQuery animate()が機能する方法は、アニメーションの状態を反映するようにDOMを更新する関数を定期的に起動して呼び出すタイマーを使用することだと思います。通常、アニメーションは比較的短く、かなりの画面領域をカバーする可能性があるため、スムーズなアニメーションを生成するために、タイマーが期限切れになり、かなり高いレートでリセットされると思われます(確認なし)。アニメーションには時間がかかるため、アニメーションの進行速度をオプションで設定できるように、アニメーション機能を変更できる場合があります。あなたの場合、およそ1秒あたり約3〜4ピクセルをカバーしているので、250ミリ秒ごとに更新するだけで済みます。

34
tvanfosson

私はこれが古い質問であることを知っています ティムは素晴らしい答えを提供しました 、しかし私は今より簡単な方法があるので、この問題の解決策を探している人のためにアップデートを投稿するべきだと思いました...

jQuery 1.4.3以降、jQueryのアニメーションが使用する間隔はjQueryを介して直接設定できます。 fx.intervalプロパティ。したがって、次のようなことを簡単に行うことができます。

jQuery.fx.interval = 50;
44
Alconja

人々はjQueryのリフレッシュレートを遅くすることに言及しました。このファイル(jquery.animation-fix.js)を使用して、jQuery1.4のタイマー関数をオーバーライドできます。

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を任意の間隔に変更します。それはミリ秒(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>
20
Tim

jQuery animateは、javascript関数 'setInterval'を使用して、数ミリ秒ごとにオブジェクトを更新します。残念ながら、jQueryの間隔はデフォルトで「13ms」です。つまり、76は毎秒更新されます。このような低速および中程度のアニメーションの多くの方法。

13msはjQueryにハードコードされています。したがって、この値を直接変更できるのはjQuery.jsのみです。遅い群れしかない場合は、100msまで上がることができます。より高速なアニメーションもある場合は、50に設定する必要があります。

SetInterval();のパラメーターを変更できます。関数customで。 'jQuery.fx.prototype {... custom:function(){...} ...}'

3

アニメーションにはループ操作が含まれ、それらは何があってもCPUを実際に処理します。

JQueryを使用するのがどれほど簡単かはわかりませんが、必要なのはアニメーションの消費サイクルが少ないことです。 aniをもう少しギザギザにする(表示がスムーズではない)か、ループを最適化するか、aniの作業を減らす必要があります。

40秒?アニメーションとしては少し長いのではないですか?それよりもう少し即効性があると思いました。

2
StingyJack

Scriptaculousでアニメーションのパフォーマンスを確認したところ、同様のCPUスパイクが見つかりました。IEの場合は約50%、Firefoxの場合はわずかに優れたパフォーマンス(16〜30%)です。どちらもDuoCorePCで実行されます。 JQueryとScriptaculousはどちらも、基盤となるCSSを変更することで機能するため、Javascriptの実装は計算コストが高くなると言っても過言ではありません。

あなたはフラッシュを使い続けるのに行き詰まっているかもしれません。

2
rtperson

Drupal 6の実稼働環境でこの修正を機能させる必要がありましたが、Timによって投稿された回答が本当に気に入っています。

JQuery更新モジュールを使用してjQuery1.3.2をインストールしているので、使用しているものと、Timの修正が設計されているjQuery1.4との間にはいくつかの違いがあります。

ティムの指示に従って、私はそこまでの道のりの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);
}
};
0
David Meister