requestAnimationFrame с clearAnimationFrame для события прокрутки - PullRequest
0 голосов
/ 25 декабря 2018

Уже много вопросов по поводу requestAnimationFrame в JavaScript, и (я думаю) я понимаю концепцию, но есть ли разница в производительности между и без cancelAnimationFrame в этом контексте?

// Setup a timer
var timeout;

// Listen for resize events
window.addEventListener('scroll', function () {

    console.log( 'no debounce' );

    // Cancel last animation, if there's one
    if (timeout) {
        window.cancelAnimationFrame(timeout);
    }

    // Setup the new requestAnimationFrame()
    timeout = window.requestAnimationFrame(function () {

        // Run our scroll functions
        console.log( 'debounced' );

    });

}, false);

безcancelAnimationFrame:

// Setup a timer
var timeout;

// Listen for resize events
window.addEventListener('scroll', function () {

    console.log( 'no debounce' );


    // Setup the new requestAnimationFrame()
    window.requestAnimationFrame(function () {

        // Run our scroll functions
        console.log( 'debounced' );

    });

}, false);

Я получаю одинаковый результат для каждого кода.

Но я хочу знать, что произойдет, если я не отменю кадр анимации.Запрошенная функция хранится где-то в памяти или что-то в этом роде?

1 Ответ

0 голосов
/ 26 декабря 2018

var isRafLogged = false;

function rafCb(now) {
  if (isRafLogged) {
    console.log('rAF callback executed at: ', now, 'ms');
  }
  requestAnimationFrame(rafCb);
}

function onWindowScroll() {
  // when in scroll, log aforescheduled rAF() only when in scroll
  isRafLogged = true;
  const now = performance.now();

  console.log('scroll callback executed at: ', now, 'ms');

  // when out of scroll, stop logging the rAF
  setTimeout(function() {
    isRafLogged = false;
  });
}

requestAnimationFrame(rafCb);

window.addEventListener('scroll', onWindowScroll);
html,
body {
  height: 10000px;
}

p {
  font-size: 200px;
  writing-mode: vertical-lr;
}
<p>.....................................................................................................................................................................................................................................................................................................................................................................</p>

Если мы планируем непрерывный отдельный цикл requestAnimationFrame, пока мы scroll, мы ясно увидим, что rAF и scroll обратные вызовыпроисходят не более одного раза за событие VSync .

Итак, возвращаясь к вашему основному вопросу

, есть ли разница в производительности между с и без cancelAnimationFrame в этом контексте?

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

Но я хочу знать, что произойдет, если я не отменю кадр анимации.Устанавливаются ли запрошенные функции где-то в памяти или что-то в этом роде?

Все запрошенные обратные вызовы кадров анимации укладываются во внутренний пул обратных вызовов , которые сбрасываются до ближайшего события Vsync.Так что технически да, единственный способ удалить запланированные обратные вызовы - это cancelAnimationFrame(), но, опять же, это не актуально в вашем случае, поскольку ваш requestAnimationFrame() обратный вызов происходит в одно и то же время с обратным вызовом scroll окна.

Надеюсь, это имеет смысл.

...