如何最小化等待touchmove的主线程

时间:2016-12-01 21:15:36

标签: javascript google-chrome-devtools chromium

我的任务是在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用于实际工作。 :(

enter image description here

注意:在移动游猎中它很快,但感觉不到这种延迟。

1 个答案:

答案 0 :(得分:0)

等待的〜10ms是从输入事件进入到主线程在生成下一帧时拾取它的时间。从 时间开始,你有~16毫秒的帧预算

您看到的是输入延迟。它不会影响你的效果的平滑性(你的JS处理程序完全在预算范围内)但它增加了~1帧的延迟(因此盒子不会完全贴在手指上)。发生这种情况是因为操作系统将输入事件传递给浏览器进程。然后将其发送到包含您的页面的渲染器进程。从那里开始,它在主线程上排队,但是在主线程准备好生成一个新帧之前不会被拾取(并且每一步都有一些排队)。一旦帧被推送到GPU,时间线中的触摸移动就会结束。

不幸的是,这很大程度上并不在你的控制范围之内,只要主线程不饱和,它就应该相对稳定。