Headroom.js — это лёгкая библиотека для управления поведением шапки страницы при прокрутке. Основная задача — динамически скрывать или показывать header в зависимости от направления скролла. Несмотря на простоту использования, некорректная интеграция может привести к лишним перерисовкам и падению производительности. Важнейший аспект работы с Headroom.js — минимизация нагрузки на браузер через оптимизацию рендеринга.
requestAnimationFrame для обновленийHeadroom.js по умолчанию реагирует на события прокрутки через
слушатель scroll. Если изменения DOM происходят напрямую в
обработчике события, это может вызвать частые
перерисовки, так как scroll-ивенты вызываются десятки раз в
секунду.
Для оптимизации применяют requestAnimationFrame:
const header = document.querySelector('.header');
let lastKnownScrollY = 0;
let ticking = false;
function onScroll() {
lastKnownScrollY = window.scrollY;
if (!ticking) {
window.requestAnimationFrame(() => {
updateHeader(lastKnownScrollY);
ticking = false;
});
ticking = true;
}
}
function updateHeader(scrollY) {
if (scrollY > 100) {
header.classList.add('header--hidden');
} else {
header.classList.remove('header--hidden');
}
}
window.addEventListener('scroll', onScroll);
В этом примере DOM обновляется только один раз за кадр, что значительно снижает нагрузку на рендер.
Каждое изменение свойства CSS, которое влияет на layout (например,
height, margin, padding) вызывает
reflow, а свойства, влияющие только на визуализацию
(opacity, transform), вызывают только
repaint, который намного дешевле.
В Headroom.js рекомендуется использовать трансформации для скрытия шапки:
.header {
position: fixed;
top: 0;
width: 100%;
transition: transform 0.3s ease;
}
.header--hidden {
transform: translateY(-100%);
}
Такой подход полностью исключает reflow при скрытии или показе шапки, ускоряя отклик и снижая нагрузку на браузер.
Даже с requestAnimationFrame иногда полезно
ограничивать частоту вызова функций, особенно при
длинных страницх. Для этого применяют методики дебаунса или
троттлинга:
function throttle(fn, wait) {
let time = Date.now();
return function() {
if ((time + wait - Date.now()) < 0) {
fn();
time = Date.now();
}
}
}
window.addEventListener('scroll', throttle(onScroll, 50));
Троттлинг предотвращает избыточные вызовы и снижает вероятность лагов при интенсивной прокрутке.
Для сложных DOM-структур важно кэшировать элементы,
к которым применяется Headroom.js, и использовать классы вместо прямого
изменения стилей через style.
Пример:
const header = document.querySelector('.header');
function updateHeader(scrollY) {
const hidden = scrollY > 100;
header.classList.toggle('header--hidden', hidden);
}
Такой подход сокращает количество операций над DOM и позволяет браузеру эффективно оптимизировать перерисовки.
На слабых мобильных устройствах анимации могут вызывать лаги. Для оптимизации можно применять медиа-запросы или feature detection, чтобы включать анимацию только на десктопах:
@media (min-width: 768px) {
.header {
transition: transform 0.3s ease;
}
}
Это снижает нагрузку на графический движок и уменьшает вероятность dropped frames при прокрутке.
Вместо постоянного отслеживания scrollY можно
использовать Intersection Observer, который отслеживает
видимость элемента в viewport без постоянного вызова обработчиков:
const observer = new IntersectionObserver(([entry]) => {
header.classList.toggle('header--hidden', !entry.isIntersecting);
}, { threshold: [0] });
observer.observe(document.querySelector('.trigger'));
Этот метод позволяет браузеру самостийно оптимизировать обновления и исключает лишние reflow/repaint.
transform и opacity.requestAnimationFrame или троттлинг снижает нагрузку.Intersection Observer, позволяет полностью снять нагрузку с
scroll-обработчиков.Эти практики обеспечивают плавное поведение шапки, минимизируют перерисовки и повышают общую производительность страницы при использовании Headroom.js.