2016-12-01 4 views
1

Моя задача - перетащить div на html-страницу и сделать это как можно быстрее, потому что целевая платформа мобильная (хром-андроид). Но я нашел ее немного лаги на хром (android), поэтому я начал профилировать приложение и обнаружил, что мои сенсорные события ждут основного потока примерно на ~ 10 мс на huawei p8.Как свести к минимуму ожидание основной темы для touchmove

Мой вопрос: как я могу свести к минимуму это время, не нашел никакого решения, похоже, что это невозможно.

вот пример jsfiddle (https://jsfiddle.net/bbvarga/p94btq6e/):

JS часть:

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

и вот скриншот из го e timeline, так как вы можете видеть, что красные линии под событиями Touch Move довольно длинные (это пока браузер ждет основного потока, он также находится под сводкой события Touch Move, вы можете видеть внизу скриншота в приложении). Реальная работа, recalc стиль, живопись, составление происходит довольно быстро по сравнению с временем ожидания.

Теперь частота кадров в этом минималистическом примере приемлема, но я чувствую, что если у меня есть изображения и другие вещи в этом div, некоторые вычисления, эти события с длинным касанием замедляют мою частоту кадров.

Если вы хотите достичь 60 кадров в секунду, у вас будет ~ 17 мс для каждого кадра, и если вы ожидаете ~ 10, у вас будет всего 7 мс для настоящей работы. :(

enter image description here

запиской:. В мобильном сафари это быстро, и не может чувствовать эту задержку

ответ

0

~ 10мс выжидания время от момента, когда событие ввода приходит, пока главный нить поднимает его вверх, когда он генерирует следующий кадр. из , что времени у вас есть ~ 16ms бюджета кадра

что вы видите на входе задержка. это не влияет на плавность вашего эффекта (ваш обработчик JS находится в пределах бюджета), но он добавляет ~ 1 кадр задержки (так что коробка doesn «точно придерживайтесь пальца»). Это происходит потому, что ОС передает входное событие в процесс браузера. Затем он отправляется процессу рендеринга, содержащему вашу страницу. Оттуда он поставлен в очередь на основной поток, но не будет поднят до тех пор, пока основной поток не будет готов к созданию нового фрейма (и на каждом шаге происходит череда очередей). Прикосновение движется по временной шкале, как только кадр будет перенесен на GPU.

К сожалению, большая часть этого не находится под вашим контролем, но она должна быть относительно постоянной, пока ваша основная нить не насыщена.