对于反应时间研究(see also this question,如果您感兴趣),我们希望控制和测量图像的显示时间。我们想说明在不同用户的机器上重绘所需的时间。
编辑:最初,我只使用内联执行进行计时,并且认为我不能相信它可以准确地测量图片在用户屏幕上可见的时间,因为绘画需要一些时间
后来,我发现了事件“MozAfterPaint”。它需要在用户的计算机上运行配置更改,并且相应的WebkitAfterPaint没有成功。这意味着我无法在用户的计算机上使用它,但我将它用于我自己的测试。我粘贴了相关的代码片段和我下面测试的结果 我还在Chrome中使用SpeedTracer手动检查了结果。
// from the loop pre-rendering images for faster display
var imgdiv = $('<div class="trial_images" id="trial_images_'+i+'" style="display:none"><img class="top" src="' + toppath + '"><br><img class="bottom" src="'+ botpath + '"></div>');
Session.imgs[i] = imgdiv.append(botimg);
$('#trial').append(Session.imgs);
// in Trial.showImages
$(window).one('MozAfterPaint', function () {
Trial.FixationHidden = performance.now();
});
$('#trial_images_'+Trial.current).show(); // this would cause reflows, but I've since changed it to use the visibility property and absolutely positioned images, to minimise reflows
Trial.ImagesShown = performance.now();
Session.waitForNextStep = setTimeout(Trial.showProbe, 500); // 500ms
// in Trial.showProbe
$(window).one('MozAfterPaint', function () {
Trial.ImagesHidden = performance.now();
});
$('#trial_images_'+Trial.current).hide();
Trial.ProbeShown = performance.now();
// show Probe etc...
这不会让我太开心。首先,中位显示持续时间比我想要的短约30毫秒。其次,使用MozAfterPaint的方差非常大(并且比内联执行更大),所以我不能简单地通过将setTimeout增加30ms来调整它。第三,这是在我相当快的计算机上,其他计算机的结果可能更糟。
这些更好。图像可见的时间通常在预期持续时间的4(有时)10毫秒内。看起来Chrome还占据了setTimeout
调用中重绘所需的时间(因此,如果图像需要重新绘制,则调用之间有504ms的差异)。
不幸的是,我无法分析和绘制SpeedTracer中许多试验的结果,因为它只记录到控制台。我不确定SpeedTracer和MozAfterPaint之间的差异是否反映了两个浏览器的差异或我使用MozAfterPaint时缺少的东西(我很确定我正确地解释了SpeedTracer输出)。
我想知道
setTimeout
。我知道requestAnimationFrame
,但似乎我们不能从使用它中获得任何好处:显然,Javascript对此并不理想,但它对我们的目的来说是最不利的(研究必须在用户自己的计算机上在线运行,要求他们安装一些会吓跑一些,Java不捆绑在Mac上OS X浏览器了。) 我们目前只允许使用当前版本的Safari,Chrome,Firefox和MSIE(性能检测功能。现在和全屏API,我还没有检查过MSIE的功能)。
答案 0 :(得分:5)
因为我还没有得到任何答案,但在编辑这个问题时学到了很多,我发布的答案就是答案。正如你所看到的那样,它仍然不是最优的,我很乐意将赏金奖励给任何改进它的人。
visibility
和绝对定位而不是display
来最小化回流。在最后一个面板中,“paint-to-paint”时间的平均值是~500ms,内联执行时序的平均值实际上分散(有意义,因为我使用相同的时间戳来终止下面的内部循环)并且相关联与“油漆到油漆”的时间。
持续时间仍有很多变化,我希望进一步减少它,但这肯定是进步。我将不得不在一些较慢的和一些Windows计算机上测试它,看看我是否真的很满意它,最初我希望所有偏差都低于10ms。
如果我制作了一个不需要用户交互的测试套件,我还可以收集更多数据,但我想在实际应用中做到这一点,以获得真实的估算。
window.requestTimeout
使用window.requestAnimationFrame window.requestTimeout = function(fn, delay) {
var start = performance.now(),
handle = new Object();
function loop(){
var current = performance.now(),
delta = current - start;
delta >= delay ? fn.call() : handle.value = window.requestAnimationFrame(loop);
};
handle.value = window.requestAnimationFrame(loop);
return handle;
};
答案 1 :(得分:4)
您是否尝试获取初始毫秒数,并在事件触发后计算差异?而不是setTimeout。类似的东西:
var startDate = new Date();
var startMilliseconds = startDate.getTime();
// when the event is fired :
(...), function() {
console.log(new Date().getTime() - startMilliseconds);
});
尝试尽可能避免使用jQuery。普通JS将为您提供更好的响应时间和更好的整体性能