3

スクリプトに取り組んでいると、私の ajax が意図したよりも約 10 倍多く riring していることに気付きました。毎秒約 35 フレームで動作します。次の設定を使用します。

function load(){ 
//other code that does not effect this
    requestAnimFrame(function(){
        load();
    });
    debug();//function i was using to catch fps
}

window.requestAnimFrame = (function(callback){
    return window.requestAnimationFrame ||
    window.webkitRequestAnimationFrame ||
    window.mozRequestAnimationFrame ||
    window.oRequestAnimationFrame ||
    window.msRequestAnimationFrame ||
    function(callback){
        window.setTimeout(callback, 100);
    };
})();

現在、google chrome は window.setTimeout(callback, 100); に入力した値を気にしていないようです。それは1かもしれないし、10000000かもしれない それは無防備に約130フレームで実行される

一方、私は setTimeout(load, 100); を使用していました。それに変更すると、すべてのブラウザが約 30fps で動作し始めます

function load(){ 
    //other code that does not effect this

        debug();//function i was using to catch fps
        setTimeout(load, 100);
    }

そのようにするのは悪い習慣ですか、それとも時代遅れですか?ポイントは、requestAnimFrameを使用している理由がよくわからないということです。オンラインで見つけたすべての例でもそれを使用しており、指定された目標を達成しているようです。そして、私が何度も何度も負荷をかけている唯一の理由は、新しい情報が得られるかどうかを確認することです..

編集そして、これを将来読む人のために。コードを 1 行ずつ実行した後、3x を説明するロジックのエラーが見つかりました。私は load() を呼び出して実行していないことを確認しましたが、

function connected(result){
    if (xmlhttp.readyState==4 && xmlhttp.status==200){
        //code that does not matter for this
    }else if (xmlhttp.status==404){
        alert("epic failure i lost the page");
    }
    d_time = new Date().getTime();
    load();
}

Connect は xmlhttp.onreadystatechange=connected によって呼び出されていました。そのため、3 セットの load(); を実行すると、何度も起動する可能性があります。私がする必要があったのはこれでした:

function connected(result){
    if (xmlhttp.readyState==4 && xmlhttp.status==200){
        d_time = new Date().getTime();
        load();
    }else if (xmlhttp.status==404){
        alert("epic failure i lost the page");
    }

}

シュミットとパトリックの両方がここで助けてくれました。私が初心者であり、間違ったことをしていたことを知らせて、シュミットします。その機能で何が起こっていたのかを正確に理解するのを手伝ってくれたパトリック

4

2 に答える 2

2

関数の定義

window.requestAnimFrame()

この方法では、他の関数が存在しない場合にのみsetTimeoutが使用されます。より明示的に次のように書き直すことができます。

window.requestAnimFrame = (function(callback){
    var theFunction;
    if (window.requestAnimationFrame) {
        theFunction = window.requestAnimationFrame;
    } else if (window.webkitRequestAnimationFrame) {
        theFunction = window.webkitRequestAnimationFrame;
    } else if (window.mozRequestAnimationFrame) {
        theFunction = window.mozRequestAnimationFrame;
    } else if (window.oRequestAnimationFrame) {
        theFunction = window.oRequestAnimationFrame;
    } else if (window.msRequestAnimationFrame) {
        theFunction = window.msRequestAnimationFrame;
    } else {
        theFunction = function(callback){
            window.setTimeout(callback, 100);
        };
    } 
    return theFunction;
})();

したがって、他の関数が存在しない場合にのみタイムアウトを使用します。この関数は、古いブラウザのように、requestAnimationFrameが存在しない場合に、requestAnimationFrameの独自の実装にフォールバックするために使用されます。それらの古いブラウザはタイムアウトを使用します。

requestAnimationFrameは、定義上、クライアントによってフレームレートが決定されます。つまり、毎秒180倍(クロムで見られるように)または毎秒1倍実行できるということです。これにより、クライアントブラウザは何が最も重要かを判断でき、不要な場合(タブがアクティブでない場合やモバイルブラウザが最小化された場合など)に画面の更新をオフにする方法が提供されます。

于 2012-12-14T00:34:11.763 に答える
1

http://jsfiddle.net/VMyn8/1/

私はあなたのfpsタイマーが間違っていると信じています。で一貫した60FPS(実際には約62)を取得していwebkitRequestAnimationFrameます。

var last = new Date(),
    frames = [],
    div = document.getElementById("fps");

(function loop(){
    var span = ((new Date()) - last)/1000;
    last = new Date();
    frames.push(span);

    if (frames.length > 100) frames.shift();

    var total = 0;    
    for (var i = 0; i < frames.length; i++)total += frames[i];    

    div.innerHTML = Math.floor(frames.length/total);
    //setTimeout(loop, 1000/60);
    webkitRequestAnimationFrame(loop);
})();

サーバーをポーリングしようとしている場合は、まったく異なるものを提案します。

(function poll(){
    // do some stuff

    setTimeout(poll, 3000); // poll every 3 seconds
    // if you are doing an ajax call, you'll want to place the timeout in the 
    // callback so you aren't initiating another call before you've received 
    // a response to the current one. 
})();
于 2012-12-14T00:43:30.480 に答える