我正在开发一个非常时间敏感的应用程序,该应用程序使用按键进行用户输入。当我在这里谈论毫秒时,我继续尝试了这样的版本:
function start() {
//stim.style.display = "block";
rt_start = new Date().getTime();
response_allowed = 1;
}
function end() {
var t = rt_end - rt_start;
//stim.style.display = "none";
log.innerHTML = t;
i++;
if (i < iterations) {
setTimeout('start();', 1000);
}
}
var rt_start;
var rt_end;
var iterations = 100;
var i = 0;
var response_allowed = 0;
var stim;
var log;
$(document).ready(function() {
document.onkeydown = function(e) {
if (response_allowed == 1) {
rt_end = new Date().getTime();
response_allowed = 0;
end();
}
};
stim = document.getElementById('stim');
log = document.getElementById('log');
start();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div id="log"></div>
<img src="https://www.gravatar.com/avatar/cfefd93404e6b0eb3cde02b4b6df4e2b?s=128&d=identicon&r=PG&f=1" id="stim" />
它工作正常,通常是低于 5ms 的计时器(只需按住一个键(。但是一旦我修改代码以显示图像(取消注释两行(,这就会减慢很多,大约 30 毫秒。
有人可以指出为什么会这样以及如何避免这种额外的延迟吗?
谢谢
我建议在可用的情况下使用DOMHighResTimeStamp(对于不提供它的浏览器使用polyfill(。
这是一个高分辨率的时间戳(设计时考虑到了准确的测量(,用于(例如(导航计时和 Web 性能 API(在 Mozilla 开发者网络中搜索,因为我不能在一篇文章中共享两个以上的链接(。
获取 DOMHighResTimeStamp 的快速方法 - 就像您使用var ts = new Date().getTime();
获取常规毫秒时间戳一样 - 是:
var ts = performance.now();
正如我上面所说,看看MDN的Web性能API。如果您的应用程序确实对时间敏感,这将非常有帮助。
编辑:
关于你的片段,在我看来,如果你按住一个键,你将始终被限制为键按下事件的分辨率(连续触发,但不是每毫秒(。如果使用文本编辑器按下字符键(连续(并检查字符每秒写入的次数,则可以轻松看到此行为。我想,这是通过操作系统设置控制的。
您还被限制在与 setTimeout/setInterval 相关的"漂移"中。你看,setTimeout 在给定的延迟后将某些内容排队等待执行,但它不能保证及时执行。这是一个"尽力而为"的场景,如果浏览器忙于做某事,它将显着漂移。含义:如果使用 setTimeout 在 1 秒后重新启用 response_allowed
变量,则可以期望它在"大约"(但不完全是(1 秒后重新启用它。