Сравнение производительности Javascript OnScroll
Допустим, я хочу добавить на сайт несколько дорогих действий, вызванных прокруткой. Например, я использую эффекты параллакса в моем jsfiddle.
Теперь я продолжаю читать, это не должно быть связано с событием напрямую, иногда следуют фрагменты, которые должны быть лучше. Просто несколько примеров:
- Присоединение обработчиков JavaScript к событиям прокрутки = ПЛОХО!
- Как развить высокую производительность на событии Scroll?
- Как сделать эффекты прокрутки быстрее?
- Слушатель события 60FPS onscroll
То, что они говорят, в основном не делают этого:
// Bad guy 1
$(window).scroll( function() {
animate(ex1);
});
или это
// Bad guy 2
window.addEventListener('scroll', onScroll, false);
function onScroll() {
animate(ex2);
}
Но используйте тайм-ауты, интервалы, requestAnimationFrame и еще много чего, например:
// Good guy
$(window).scroll( function() {
scrolling1 = true;
});
setInterval( function() {
if (scrolling1) {
scrolling1 = false;
animate(ex3);
}
}, 50 );
Итак, я пошел и добавил параметры, которые я нашел в ссылках выше, в jsfiddle, который пытается сравнить их, добавив счетчик для каждого подхода, например так:
// Test
$(window).scroll( function() {
counter = counter + 1;
// output result of counter
animate(ex1);
});
Лучше всего проверить полную версию jsfiddle или использовать ее для старых браузеров: Scrolltest (то же самое, но только не в jsfiddle)
Итог: все, что работает гладко, примерно столько же вычислений. Если я могу жить с изменчивыми эффектами, возможно, я смогу спасти некоторые ресурсы. И против всего, что я читаю, это кажется мне логичным!
Первый вопрос: я что-то упустил или это действительный тест? Если это неверно, как я могу проверить правильно?Изменить: Чтобы уточнить, я хочу проверить, если какой-либо из перечисленных методов сохранить производительность вообще.
Второй вопрос: если это действительно так, почему все нервничают по поводу прокрутки? Если для плавной анимации требуется 5000 вычислений по всему сайту, то нет способа ее изменить?
(Ну, иногда я использую проверки, чтобы определить, находится ли объект в области просмотра или нет, но, честно говоря, я даже не знаю, стоят ли эти проверки так же дорого, как сам запрещенный код, особенно если они включают пять различных переменных, таких как offset, windowHeight, scrolltTop, getBoundingClientRect и outerHeight...)
2 ответа
Таким образом, @SirPeople уже правильно ответил на ваш первый вопрос, это действительно хороший тест, чтобы увидеть, как часто вызывается функция animate, но это плохой тест для сравнения производительности различных фрагментов.
Это запись исполнения исключения:
Функция animate
совсем не дорого. Я сделал запись исполнения (следующий снимок), которая показывает, что на одну итерацию, которую я посмотрел, уходит от 0,64 мс до 1,29 мс (точки 1-5). И как только функция завершена, перерисовка не занимает времени (пункт 6), что может быть связано с тем, что на странице почти нет содержимого. Если мы посмотрим на время, то увидим, что все пять функций анимации и перерисовка происходят менее чем за 10 мс, что в обычных условиях означает, что мы можем получить плавную анимацию 60 кадров в секунду (точка 7).
Кроме того, если мы хотим сравнить прослушиватели событий onscroll, нам нужно протестировать каждого из них по отдельности и сравнить результаты. Если бы один из слушателей действительно блокировал это, это оказало бы влияние на всю страницу, и без отладки производительности вы бы не знали, кто это был.
Я сделал два jsfiddles window.scroll и RAF. И, к моему удивлению, нет никакой разницы.
Почему люди обеспокоены этим?
Как вы можете видеть в jsfiddles, связанном выше, если обработчики событий становятся слишком большими, вся страница будет отставать.
Что теперь?
Я не гуру производительности, но:
- Возможно, одно из других решений является правильным
- Мы можем пометить ваших слушателей событий как пассивные, хотя в моем тесте он не улучшился вообще https://developers.google.com/web/updates/2016/06/passive-event-listeners
- Мы можем оптимизировать прослушиватель событий, удалив эффекты параллакса
- Также есть новая вещь, которая называется Intersection Observer, которая должна быть намного быстрее, я не тестировал ее https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API
Я не совсем уверен, правильно ли я понял ваши вопросы и все ваши заявления, но постараюсь дать вам ответ:
- Я что-то пропустил или это действительный тест? Если это неверно, как я могу проверить правильно?
Это допустимый тест, если вы измеряете, сколько раз была вызвана функция, это, конечно, будет зависеть от браузера, SO, если улучшен графический процессор, и некоторых других параметров теста, которые уже были прокомментированы в вашем вопросе.
Если мы считаем это измерение правильным, то можно сказать, что использование timeouts или requestAnimationFramework может сэкономить время, потому что мы в основном следуем принципам устранения или регулирования. По сути, мы не хотим запрашивать или вызывать функцию больше раз, чем необходимо. В случае таймера мы поставим в очередь меньше вызовов функций, а в случае requestAnimationFrame, потому что он ставит вызовы в очередь перед перерисовкой и будет выполнять их последовательно. По тайм-аутам может случиться так, что вычисления будут перекрываться, если они очень тяжелые
Я нашел лучший ответ в том, почему с помощью requestAnimationFrame объясняются основные проблемы с анимацией в браузере, такие как сдвиг, мерцание или пропуск кадров. Это также включает в себя хорошее демо.
Я думаю, что ваш метод тестирования правильный, вы также должны правильно его интерпретировать, возможно, вызовы близки к одному и тому же номеру из-за вашего оборудования и вашего движка, но, как уже было сказано, отладка и регулирование снижают производительность.
Здесь также еще одна статья, поддерживающая не прикреплять обработчики к прокрутке окна из Twitter. (Отказ от ответственности: эта статья за 2011 год, и браузеры по-разному занимаются оптимизацией прокрутки).
- почему все нервничают по поводу прокрутки? Если для плавной анимации требуется 5000 вычислений по всему сайту, то нет способа ее изменить?
Я не думаю, что при снижении производительности возникает нервозность, но пользовательский опыт будет худшим из-за вышеупомянутых проблем с анимацией, которые может вызвать ваше превышение прокрутки, или даже если произойдет десинхронизация с вашим таймером, вы все равно можете получить то же самое ". проблемы с производительностью. Люди просто рекомендуют сохранять вызовы для прокрутки, потому что: человеческое визуальное постоянство не требует сверхвысокой частоты кадров, и поэтому бесполезно пытаться показывать изображения чаще. Для более сложных вычислений или тяжелой анимации браузеры уже работают над оптимизацией, как, например, вы проверили, некоторые браузеры оптимизировали это по сравнению с 2, 3 или 6 годами ранее написанными статьями.