3

在编写脚本时,我注意到我的 ajax 比预期的要多 10 倍,所以我输入了一个“fps 计数器”,并注意到不是像预期的那样每秒运行 10 次,而是每秒运行大约 130 次 ie/ff/歌剧大约每秒 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);
    };
})();

现在谷歌浏览器似乎并不关心我在 window.setTimeout(callback, 100); 它可能是 1 也可能是 10000000 它以大约 130 帧的速度运行,而其余的似乎足够接近它(总是大约是预期的 3 倍)并且我已经确保我没有多次调用 load()

另一方面,我曾经使用 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,然后我在网上找到的所有示例也都使用它,而且它似乎实现了给定的目标。我一遍又一遍地发射负载的唯一原因是检查并查看是否有任何新信息要下来..

编辑对于那些将来阅读本文的人。通过代码逐行运行后,我发现逻辑错误解释了我的 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");
    }

}

所以施密特和帕特里克都在这里帮忙。施密特让我知道我是一个菜鸟并且做错了。patrick 帮助我准确了解该功能发生了什么

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 的帧率将由客户端确定。这意味着它可以每秒运行 180 倍(就像您在 chrome 中看到的那样)或每秒 1 倍。它允许客户端浏览器确定最重要的是什么,并使其在没有必要时关闭屏幕刷新的方法(就像选项卡未处于活动状态或移动浏览器最小化时)。

于 2012-12-14T00:34:11.763 回答
1

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

我确实相信您的 fps 计时器是错误的。我在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 回答