6

要素の背景色をフェードするスクリプトを作成しました。setTimeout()を使用して、5ミリ秒ごとに色を段階的に変更します。スクリプトは、一度に1つのものの背景色をフェードするだけの場合はうまく機能しますが、たとえば、一度に50個の要素をフェードする場合、速度は5ミリ秒よりもはるかに遅くなります。同時に実行されているsetTimeout()。たとえば、通常1秒で実行されるはずのフェードは、一度に50個の要素をフェードする場合、30秒かかる場合があります。

これを克服する方法はありますか?

誰かがアイデアを持っている場合のスクリプトは次のとおりです。

function fadeBackground(elementId, start, end, time) {
    var iterations = Math.round(time / 5);

    var step = new Array(3);

    step[0] = (end[0] - start[0]) / iterations;
    step[1] = (end[1] - start[1]) / iterations;
    step[2] = (end[2] - start[2]) / iterations;

    stepFade(elementId, start, step, end, iterations);
}

function stepFade(elementId, cur, step, end, iterationsLeft) {
    iterationsLeft--;

    document.getElementById(elementId).style.backgroundColor
        = "rgb(" + cur[0] + "," + cur[1] + "," + cur[2] + ")";

    cur[0] = Math.round(end[0] - step[0] * iterationsLeft);
    cur[1] = Math.round(end[1] - step[1] * iterationsLeft);
    cur[2] = Math.round(end[2] - step[2] * iterationsLeft);

    if (iterationsLeft > 1) {
        setTimeout(function() {
            stepFade(elementId, cur, step, end, iterationsLeft);
        }, 5);
    }
    else {
        document.getElementById(elementId).style.backgroundColor 
            = "rgb(" + end[0] + "," + end[1] + "," + end[2] + ")";
    }
}

これは次のように使用されます:

fadeBackground("myList", [98,180,232], [255,255,255], 1000);
4

2 に答える 2

12

これは、著者が Gmail のタイマーに関する作業について議論している Googleの記事です。彼らは、頻繁に急速にタイマーを使用する場合、単一の高頻度タイマーを使用する方が複数のタイマーを使用するよりも高速であることを発見しました。

5 ミリ秒ごとに起動する 1 つのタイマーを設定し、フェードする必要があるすべての要素を、フェード プロセスのどこにあるかを追跡するデータ構造に追加できます。次に、1 つのタイマーがそのリストを調べて、トリガーされるたびに各要素の次のフェードを実行できます。

一方で、独自のアニメーション フレームワークを展開するのではなく、MootoolsJQueryなどのライブラリを使用してみましたか? 彼らの開発者は、これらの種類の操作を最適化するために多くの作業を行ってきました.

于 2009-07-30T20:36:31.043 に答える
4

まず第一に、ブラウザによっては最小タイムアウトが通常 10 ~ 15 ミリ秒であることをスクリプトが考慮していません。このトピックに関する私の投稿を見ることができます。内部には、一般的なブラウザーの表と、それを測定するプログラムへのリンクが含まれているため、自分で主張を確認できます。申し訳ありませんが、5 ミリ秒ごとの繰り返しは希望的観測です。

次に、タイマーは割り込みではありません。それらには魔法はありません。ブラウザで実行されているものを中断してペイロードを実行することはできません。代わりに、実行中のコードが終了し、ブラウザーがコントロールとタイマーを実行する機能を取り戻すまで延期されます。50 個の要素のフェードには時間がかかります。特にブラウザーの遅延モデル全体を考慮すると、5 ミリ秒以上かかると思います。DOM を更新すると、ブラウザーはその視覚的表現を更新します…ある時点で。

最後にポジティブな言葉で締めくくります。

  • 50 個の要素を個別にフェードアウトする代わりに、それらをグループ化してその親をフェードアウトしてみてください。
  • UI でよりクリエイティブに。一度に多くの独立した要素をフェードアウトする必要のない解決策を考えてみてください。
  • バックグラウンドの仮定が正しいことを常に確認してから、それらに基づいて設計してください。
  • 可能であれば、最新のブラウザーをターゲットにしてみてください。私の個人的な経験から、Google Chrome はタイマーに非常に優れており、その JavaScript エンジン (V8) は非常に高速です。
于 2009-07-31T01:29:16.227 に答える