jquery 精确控制和测量图像的显示时间

3z6pesqy  于 2023-03-07  发布在  jQuery
关注(0)|答案(2)|浏览(185)

对于一个React时间的研究(如果你感兴趣的话,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...

比较使用MozAfterPaint和内联执行测量的持续时间的结果。

这让我不太高兴。首先,中值显示持续时间比我想要的短了大约30ms。其次,使用MozAfterPaint的方差相当大(比内联执行的方差大),所以我不能简单地通过将setTimeout增加30ms来调整它。第三,这是在我相当快的计算机上,其他计算机的结果可能更差。

SpeedTracer的结果

这些更好。图像可见的时间通常在4%以内(有时)预期持续时间的10毫秒。看起来Chrome也考虑了setTimeout调用中重绘所需的时间(所以有504ms的差异之间的调用,如果图像需要重画).不幸的是,我无法分析和绘图的结果,许多试验在SpeedTracer,因为它只记录到控制台。我不确定SpeedTracer和MozAfterPaint之间的差异是否反映了两个浏览器的差异或我使用MozAfterPaint时缺少的东西(我相当确定我正确地解释了SpeedTracer的输出)。

问题

我想知道
1.我如何测量它在用户机器上实际可见的时间,或者至少在不同的测试计算机上获得一组不同浏览器(Chrome、Firefox、Safari)的可比数字?
1.我可以补偿渲染和绘制时间以达到500毫秒的实际可见性吗?如果我必须依赖于通用补偿,那会更糟,但仍然比显示图像的持续时间短,以至于用户在有点慢的计算机上看不到它们要好。
1.我们使用setTimeout。我知道requestAnimationFrame,但似乎我们不能从使用它中获得任何好处:
研究应该在整个研究期间处于焦点状态,获得+/-500ms的显示比一定数量的fps更重要,我的理解正确吗?
显然,Javascript对此并不理想,但它对我们的目的来说是最不坏的(这项研究必须在用户自己的电脑上在线运行,要求他们安装一些东西会吓跑一些人,Java不再捆绑在Mac OS X浏览器中)。
目前我们只允许当前版本的Safari、Chrome、Firefox,也许还有MSIE(www.example.com和全屏API的功能检测,我还没有检查MSIE的功能)。performance.now and fullscreen API, I haven't checked how MSIE does yet) at the moment.

sauutmhj

sauutmhj1#

因为我还没有得到更多的答案,但是在编辑这个问题的时候学到了很多,所以我把我的进步作为答案贴出来。正如你所看到的,它仍然不是最佳的,我很乐意奖励任何在这方面有所改进的人。
统计数据

  • 在最左边的面板中,您可以看到导致我怀疑所得到的时间估计的分布。
  • 中间的面板显示了我在缓存选择器、重新排序一些调用、使用更多链接、通过使用visibility和绝对定位而不是display来最小化回流之后所实现的效果。
  • 最右边的面板显示了我在Joe Lambert中使用requestAnimationFrame修改后得到的结果。我在reading a blogpost about rAF now having sub-millisecond precision too之后这样做了。我认为它只会帮助我平滑动画,但显然它也有助于获得更好的 * 实际显示 * 持续时间。

结果

在最后一个面板中,"绘制到绘制"计时的平均值约为500ms,内联执行计时的平均值实际上是分散的(有意义,因为我使用相同的时间戳来终止下面的内部循环),并与"绘制到绘制"计时相关。
在持续时间上仍然有很大的差异,我很想进一步减少它,但这绝对是一个进步。我必须在一些较慢的电脑和一些Windows电脑上测试它,看看我是否真的对它满意,最初我希望所有的偏差都在10ms以下。
如果我制作了一个不需要用户交互的测试套件,我还可以收集更多的数据,但我希望在实际应用程序中这样做,以获得现实的估计。

window.requestTimeout正在使用窗口。请求动画帧

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;
};

编辑:

一个answer to another question of mine链接到一个good new article

r6hnlfcb

r6hnlfcb2#

您是否尝试获取初始毫秒数,并在事件触发后计算差值?而不是setTimeout。类似于:

var startDate = new Date();
var startMilliseconds = startDate.getTime();

// when the event is fired :
(...), function() {
    console.log(new Date().getTime() - startMilliseconds);
});

如果可能的话,尽量避免使用jQuery。plain JS会给予你更好的响应时间和更好的整体性能

相关问题