2016-10-27 4 views
1

Я пришел через этот пример на MDN, который использует requestAnimationFrame вместо setTimeout:Есть ли какое-либо преимущество использования requestAnimationFrame вместо SetTimeout для дребезга/дросселя

// Reference: http://www.html5rocks.com/en/tutorials/speed/animations/ 

var last_known_scroll_position = 0; 
var ticking = false; 

function doSomething(scroll_pos) { 
    // do something with the scroll position 
} 

window.addEventListener('scroll', function(e) { 
    last_known_scroll_position = window.scrollY; 
    if (!ticking) { 
    window.requestAnimationFrame(function() { 
     doSomething(last_known_scroll_position); 
     ticking = false; 
    }); 
    } 
    ticking = true; 
}); 

И это заставило меня задуматься, можно ли использовать requestAnimationFrame вместо setTimeout(fn, 0) и если есть какое-то преимущество для этого? Я googled, и кажется, что все сравнения выполняются в контексте анимации, но как насчет несвязанной функциональности - например, debounce/throttle или просто, если вам нужно запустить код после перерисовки?

+0

SetTimeout регистрирует событие для необходимого тика. Поэтому, если перед вами большая задача, которая принимает 5 тиков, ваша функция будет выполняться позже. Это может привести к некоторым проблемам, если у вас есть одна и та же функция, работающая при каждом тике. requestAnimationFrame будет пропускать все отложенные задачи и процессы на основе текущего времени. Таким образом, в этом случае будет выполняться только последняя задача. Вы можете проверить следующее сообщение: http://stackoverflow.com/questions/13935262/settimeout-or-setinterval-or-requestanimationframe – Rajesh

+0

Преимущество RequestAnimationFrame заключается в том, что он предназначен для работы во время ваших мониторов следующий розыгрыш. IOW Предназначен для предотвращения мерцания/разрыва. Из-за этого преимущества setTimeout в HTML5 он может запускать каждые 4 мс, поэтому быстрее. Но я верю, что самый быстрый - Postmessage. – Keith

ответ

1

RequestAnimationFrame хорошо, если вы хотите убедиться, что вы не делаете ненужной работы, потому что вы что-то изменили между двумя обновлениями кадра.

В самом деле, requestAnimationFrame не полезен ни для чего, кроме анимации, потому что он может ждать только 16,666 миллисекунды (если нет запаздывания), поэтому вам нужно объединить несколько друг с другом. Но если вы соедините его с setTimeout, вы сможете подождать отдельное количество миллисекунд, а также убедитесь, что вы нарисовали все в нужное время.

1

requestAnimationFrame вызывается в то время, когда браузер находится на этапе перерисовки. Поэтому теоретически это должно избегать мерцания/дрожания, если вы попытаетесь синхронизировать свойства элементов (например, положение) с положением прокрутки.

setTimeout будет называться после того, как минимум n миллисекунд, поэтому обратный вызов может быть вызван несколько раз до следующей перекраски и вы еси использование процессора, или несколько последовательных перерисовки произойдет без того обратного вызова вызывается, что приведет к мерцанию/jittering, если вы попытаетесь синхронизировать свойства элементов со строкой.

1

Помимо вышеуказанных ответов,

При использовании requestAnimationFrame анимации будет работать только тогда, когда на вкладке (или окно) видна пользователю. Это означает меньшую загрузку процессора, графического процессора и памяти, следовательно, совместимость с батареями. Это особенно важно для мобильных устройств, которые обычно имеют относительно короткий срок службы батареи.

Но для гладкой анимации мы должны заботиться о том, чтобы наш рендеринг кадров происходил менее чем за 16 мс, поэтому обратный вызов должен быть как можно меньше для анимации 60 кадров в секунду.