JavaScript是否提供高分辨率计时器?

sys*_*rpl 40 javascript animation

JavaScript是否提供高分辨率计时器?

我从头开始编写了一些游戏引擎,一些是C语言,一些是Java,一些是Flash.在动画和交互式图形方面,我总是遵循相同的基本模型.使用以下设计创建基本类/结构:

void init() { /* Called once, preload essential resources here. */ }
void update(double time) { /* Updates game/animation state using high resolution time. */ }
void render(double time) { /* Updates screen graphics using high resolution time. */ }

void run()
{
    double time;
    init();
    while (!done)
    {
        time = queryTime();
        update(time);
        render(time);
    }
}
Run Code Online (Sandbox Code Playgroud)

时间对平滑动画和游戏状态计算非常重要.在本机代码Windows中,我使用QueryPerformanceCounter()QueryPerformanceFrequency()执行queryTime()每个游戏循环中的角色并将时间传递给更新/渲染.在Java中,我使用System.nanoTime().

什么是JavaScript中的等价物?也就是说,某些函数queryTime()返回具有高精度(亚毫秒)的时间值.从我所听到的,你可以用JavaScript获得的最佳准确度大约是15毫秒......这对动画来说太可怕了.

h3r*_*3r3 92

几乎所有现代浏览器都提供高分辨率计时器.这是"高分辨率时间"W3C标准:http://www.w3.org/TR/hr-time/#sec-DOMHighResTimeStamp.

它允许您通过调用window.performance.now()获得亚毫秒级的准确时间戳.这将返回以ms为单位的时间戳,但它是一个浮点数,因此您仍然可以获得亚毫秒级的分辨率.

很老的浏览器可能会实现此标准的"前缀"版本,例如用于实现window.performance.webkitNow()的基于WebKit的浏览器

下面是一些代码,您可以使用这些代码在可用时获得准确的时间戳,否则回退到标准精度:

if (window.performance.now) {
    console.log("Using high performance timer");
    getTimestamp = function() { return window.performance.now(); };
} else {
    if (window.performance.webkitNow) {
        console.log("Using webkit high performance timer");
        getTimestamp = function() { return window.performance.webkitNow(); };
    } else {
        console.log("Using low performance timer");
        getTimestamp = function() { return new Date().getTime(); };
    }
}

getTimestamp();
Run Code Online (Sandbox Code Playgroud)

请注意,此getTimestamp()函数不返回表示当前日期/时间的值.返回值只能用于通过减去两个不同的时间戳来测量时间段.例如

var t1 = getTimestamp();
//... some other code
var t2 = getTimestamp();
console.log("Time delta: " + (t2 - t1));
Run Code Online (Sandbox Code Playgroud)

  • "看起来像Chrome`性能.现在()`现在有微秒分辨率. (2认同)

kat*_*ugh 9

而不是while (true)/ setInterval,使用递归requestAnimationFrame.它将比基于超时的动画运行更顺畅.如果您需要动画以较慢的路径运行,它会提供时间戳.


mwc*_*wcz 8

请参阅@ h3r3的答案 - 这是正确的答案.

毫秒是您在JavaScript中可以期待的最好的.而且,就像你说的那样,它不是很准确.请参阅Stack Overflow问题JavaScript中的Microsecond时序.

timer.js旨在提供高达微秒的分辨率,但它仅适用于谷歌浏览器.

更新:timer.js并没有支持微秒分辨率.它只是将毫秒计数乘以1000.

对不起,没有更好的消息!

  • 嗯,很高兴知道timer.js至少做了那么多,乘以1000是非常艰难的. (6认同)

Ole*_*kin 6

截至目前(2013年2月25日),Chrome 24的高性能时代质量非常糟糕.

var old = 0; 

for (var i=0; i<10; i++) {
    var t = window.performance.now(); 
    var d = t - old; 
    old = t; 
    console.log(t + ' += ' +d); 
}
Run Code Online (Sandbox Code Playgroud)

输出这样的东西:

609689.000000013 += 609689.000000013
609689.9999999441 += 0.9999999310821295
609689.9999999441 += 0
609689.9999999441 += 0
609689.9999999441 += 0
609690.9999999916 += 1.0000000474974513
609690.9999999916 += 0
609690.9999999916 += 0
609691.9999999227 += 0.9999999310821295
609691.9999999227 += 0
Run Code Online (Sandbox Code Playgroud)

这表明了这一点

1)很少采样

2)精度仍然在1ms左右,而不是在微秒范围内.