Обработчики ввода являются потенциальной причиной проблем с производительностью в ваших приложениях, поскольку они могут блокировать завершение кадров и вызывать дополнительную и ненужную работу по макету.
Обработчики ввода являются потенциальной причиной проблем с производительностью в ваших приложениях, поскольку они могут блокировать завершение кадров и вызывать дополнительную и ненужную работу по макету.
Краткое содержание
- Избегайте длительных обработчиков ввода; они могут блокировать прокрутку.
- Не вносите изменения в стиль обработчиков ввода.
- Откажитесь от своих обработчиков; сохранять значения событий и обрабатывать изменения стиля в следующем обратном вызове requestAnimationFrame.
Избегайте длительных обработчиков ввода
В самом быстром случае, когда пользователь взаимодействует со страницей, поток компоновщика страницы может принимать сенсорный ввод пользователя и просто перемещать контент. Это не требует никакой работы со стороны основного потока, где выполняются JavaScript, макет, стили или отрисовка.
Однако если вы прикрепляете обработчик ввода, например touchstart
, touchmove
или touchend
, поток компоновщика должен будет дождаться завершения выполнения этого обработчика, поскольку вы можете выбрать вызов preventDefault()
и остановить сенсорную прокрутку. Даже если вы не вызываете preventDefault()
компоновщику придется ждать, и поэтому прокрутка пользователя блокируется, что может привести к зависаниям и пропущенным кадрам.
Короче говоря, вы должны убедиться, что любые запускаемые вами обработчики ввода должны выполняться быстро и позволять наборщику выполнять свою работу.
Избегайте изменения стиля в обработчиках ввода
Обработчики ввода, такие как прокрутка и касание, планируются для запуска непосредственно перед любыми обратными вызовами 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);
Это также дает дополнительное преимущество: ваши обработчики ввода остаются легкими, и это здорово, потому что теперь вы не блокируете такие вещи, как прокрутка или касание дорогостоящего в вычислительном отношении кода!