Отмените обработчики ввода

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

Paul Lewis

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

Краткое содержание

  • Избегайте длительно работающих обработчиков ввода; они могут блокировать прокрутку.
  • Не вносите изменения в стиль обработчиков ввода.
  • Замедлите обработку событий; сохраняйте значения событий и обрабатывайте изменения стиля в следующем коллбэке requestAnimationFrame.

Избегайте длительно работающих обработчиков ввода.

В самом быстром случае, когда пользователь взаимодействует со страницей, поток композитора страницы может принять ввод касания пользователя и просто переместить контент. Это не требует работы со стороны основного потока, где выполняются JavaScript, разметка, стили или отрисовка.

Непринудительная прокрутка; задержка между касанием пользователя и подтверждением графического процессора минимальна при использовании только композитора.

Однако, если вы добавите обработчик ввода, например touchstart , touchmove или touchend , поток композитора должен будет дождаться завершения выполнения этого обработчика, поскольку вы можете вызвать preventDefault() и остановить прокрутку касанием. Даже если вы не вызовете preventDefault() , композитору придется ждать, и, следовательно, прокрутка пользователя будет заблокирована, что может привести к заиканию и пропуску кадров.

Интенсивная прокрутка; после касания пользователем прокрутка блокируется, а выделение ресурсов графического процессора задерживается обработчиком 'onTouchMove'.

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

Избегайте изменений стиля в обработчиках ввода.

Обработчики ввода, такие как обработчики прокрутки и касания, запланированы для выполнения непосредственно перед любыми коллбэками requestAnimationFrame .

Если вы внесёте визуальные изменения внутри одного из этих обработчиков, то в начале вызова requestAnimationFrame будут ожидаться изменения стиля. Если же вы затем прочитаете визуальные свойства в начале вызова requestAnimationFrame, как предлагается в совете « Избегайте больших, сложных макетов и перегрузки макетами », вы запустите принудительную синхронную компоновку!

Интенсивная прокрутка; считывание стиля по расписанию после requestAnimationFrame приводит к принудительной синхронизации макета.

Отложите обработку прокрутки.

Решение обеих вышеуказанных проблем одинаково: визуальные изменения всегда следует откладывать до следующего вызова функции обратного вызова requestAnimationFrame :

function onScroll (evt) {

    // Store the scroll value for laterz.
    lastScrollY = window.scrollY;

    // Prevent multiple rAF callbacks.
    if (scheduledAnimationFrame)
    return;

    scheduledAnimationFrame = true;
    requestAnimationFrame(readAndUpdatePage);
}

window.addEventListener('scroll', onScroll);

Это также дает дополнительное преимущество в том, что ваши обработчики ввода остаются легкими, что замечательно, потому что теперь вы не блокируете такие вещи, как прокрутка или касание, с помощью ресурсоемкого кода!