我的任务是在html页面中拖动div,并尽可能快地执行,因为目标平台是移动的(chrome android)但是我发现它在chrome(android)上有点滞后,所以我开始分析应用程序,发现我的触摸事件在huawei p8上等待大约10ms的主线程。
我的问题是如何才能最大限度地缩短这段时间,没有找到任何解决方案,似乎无法实现。
这是一个示例jsfiddle(https://jsfiddle.net/bbvarga/p94btq6e/):
js part:
document.addEventListener('touchmove', function(e) {
e.preventDefault();
})
var box = document.getElementById('box');
var x = 0;
var y = 0;
var px = 0;
var py = 0;
var handler = null;
function paint() {
box.style.setProperty(
'transform',
`translate3d(${px}0px, ${py}px, 0px)`,
'important'
);
handler = null;
}
box.addEventListener('touchstart', function(e) {
console.log('ts');
x = e.touches[0].pageX;
y = e.touches[0].pageY;
});
box.addEventListener('touchend', function() {
console.log('te');
if (handler) {
window.cancelAnimationFrame(handler);
handler = null;
}
});
box.addEventListener('touchmove', function(e) {
console.log('tm');
px = e.touches[0].pageX;
py = e.touches[0].pageY;
if (!handler) {
window.requestAnimationFrame(paint);
}
});
HTML:
<div id="container">
<div id="wrapper">
<div id="box">
</div>
</div>
</div>
的CSS:
#container {
position: fixed;
top: 0;
right: 0;
bottom: 0;
left: 0;
color: #efefef;
}
#wrapper {
width: 100%;
height: 100%;
position: relative;
}
#box {
position: absolute;
background-color: green;
width: 100px;
height: 100px;
}
这里是来自时间轴的屏幕截图,因为你可以看到Touch Move事件下的红线很长(当浏览器等待主线程时,它就是红线,它是&#39; s在Touch Move事件的摘要下,您可以在附加的屏幕截图的底部看到)。与等待时间相比,真正的工作,重新考虑风格,绘画,作曲的速度非常快。
现在这个简约示例中的帧速率是可以接受的,但是我觉得如果我有图像,以及其他东西在那个div,一些计算,这些长触摸移动事件会降低我的帧速率。
如果你想要达到60fps,你每帧只需要17ms,如果等待~10,你只有7ms用于实际工作。 :(
注意:在移动游猎中它很快,但感觉不到这种延迟。
答案 0 :(得分:0)
等待的〜10ms是从输入事件进入到主线程在生成下一帧时拾取它的时间。从 时间开始,你有~16毫秒的帧预算
您看到的是输入延迟。它不会影响你的效果的平滑性(你的JS处理程序完全在预算范围内)但它增加了~1帧的延迟(因此盒子不会完全贴在手指上)。发生这种情况是因为操作系统将输入事件传递给浏览器进程。然后将其发送到包含您的页面的渲染器进程。从那里开始,它在主线程上排队,但是在主线程准备好生成一个新帧之前不会被拾取(并且每一步都有一些排队)。一旦帧被推送到GPU,时间线中的触摸移动就会结束。
不幸的是,这很大程度上并不在你的控制范围之内,只要主线程不饱和,它就应该相对稳定。