2

ページ上でJavaScriptコードの一部を継続的に実行し、使用可能なすべてのCPU時間を費やして、ブラウザーの機能と応答性を同時に実現したいと考えています。

コードを継続的に実行すると、ブラウザーのUIがフリーズし、ブラウザーが文句を言い始めます。今、私はゼロタイムアウトをに渡しますsetTimeout。これは、小さなチャンクの作業を実行し、にループバックしsetTimeoutます。これは機能しますが、使用可能なすべてのCPUを使用しているわけではないようです。あなたが考えるかもしれないこれを行うためのより良い方法はありますか?

更新:より具体的には、問題のコードはフレームをcanvas継続的にレンダリングしています。ここでの作業単位は1フレームです。可能な限り最大のフレームレートを目指しています。

4

4 に答える 4

3

おそらくあなたが望むのは、ページ上で発生するすべてを一元化し、requestAnimationFrameを使用してすべての描画を行うことです。したがって、基本的には、次のような関数/クラスがあります(Mootoolsクラスに慣れているいくつかのスタイル/構文エラーを許す必要があります。これをアウトラインとして使用してください)

var Main = function(){
   this.queue = [];
   this.actions = {};

   requestAnimationFrame(this.loop)
}

Main.prototype.loop = function(){
   while (this.queue.length){
       var action = this.queue.pop();
       this.executeAction(e);
   }

   //do you rendering here
   requestAnimationFrame(this.loop);
}

Main.prototype.addToQueue = function(e){
   this.queue.push(e);
}

Main.prototype.addAction = function(target, event, callback){
    if (this.actions[target] === void 0) this.actions[target] = {};
    if (this.actions[target][event] === void 0) this.actions[target][event] = [];

    this.actions[target][event].push(callback);
}

Main.prototype.executeAction = function(e){
    if (this.actions[e.target]!==void 0 && this.actions[e.target][e.type]!==void 0){
        for (var i=0; i<this.actions[e.target][e.type].length; i++){
            this.actions[e.target][e.type](e);
        }
    }
}

したがって、基本的には、このクラスを使用して、ページで発生するすべてを処理します。すべてのイベントハンドラーはonclick='Main.addToQueue(event)'、ページにイベントを追加するか、または追加したい場合は、イベントをキューに追加するように指示し、Main.addActionを使用して、それらのイベントを実行したいものに向けます。このようにして、キャンバスの再描画が完了するとすぐに、また再描画される前に、すべてのユーザーアクションが実行されます。キャンバスが適切なフレームレートでレンダリングされる限り、アプリは応答性を維持する必要があります。

編集:requestAnimationFrame(this.loop)の「this」を忘れた

于 2012-12-17T06:15:35.797 に答える
2

Webワーカーは試してみるものです

https://developer.mozilla.org/en-US/docs/DOM/Using_web_workers
于 2012-12-17T05:30:55.387 に答える
1

呼び出しごとに行う作業量を変更することで、パフォーマンスを調整できます。あなたの質問では、あなたは「小さな仕事」をしていると言います。実行される作業の量を制御するパラメーターを確立し、さまざまな値を試してください。

処理を行う前に、タイムアウトを設定することもできます。そうすれば、処理に費やされた時間は、ブラウザが設定した最小値にカウントされます。

私が使用する手法の1つは、反復をカウントする処理ループにカウンターを設定することです。次に、その関数で、たとえば1秒の間隔を設定し、カウンターを表示してゼロにクリアします。これにより、行った変更の影響を測定するための大まかなパフォーマンス値が提供されます。

一般に、これは特定のブラウザ、さらにはブラウザのバージョンに大きく依存する可能性があります。調整可能なパラメーターとパフォーマンス測定を使用すると、フィードバックループを実装してリアルタイムで最適化できます。

于 2012-12-17T06:39:50.490 に答える
0

強制window.postMessage()する最小時間の制限を克服するために使用できます。setTimeout詳細については、この記事を参照してください。デモはこちらから入手できます。

于 2012-12-17T08:56:12.333 に答える