Работа с событиями изменения размера окна (resize) в
браузере является одной из ключевых тем при использовании
ScrollMagic. Из-за того, что браузер может генерировать
десятки и сотни событий resize при одном изменении размера окна, без
оптимизации производительность страницы существенно падает, особенно
если сцены ScrollMagic пересчитываются на каждом событии.
ScrollMagic опирается на расчёт размеров контейнеров и элементов для корректного определения триггеров и продолжительности сцен. Ключевые методы:
scene.update() – пересчитывает позицию
сцены относительно текущего скролла и размеров.controller.update() – обновляет все
сцены в контроллере.При каждом событии resize вызывается
пересчет, что может привести к серьёзной нагрузке, если
сцен много или на странице сложная анимация.
window.addEventListener("resize", function() {
controller.update();
});
Этот подход корректен, но создаёт проблему: множество лишних вызовов, которые тормозят рендеринг.
Для оптимизации применяют дебаунсинг – ограничение
частоты вызова функции до одного раза за определённый промежуток
времени. В JavaScript это реализуется через setTimeout:
let resizeTimeout;
window.addEventListener("resize", function() {
clearTimeout(resizeTimeout);
resizeTimeout = setTimeout(function() {
controller.update();
}, 200);
});
Пояснение:
clearTimeout отменяет предыдущий вызов.controller.update() будет выполнена
только после 200 мс без новых событий resize.Этот подход значительно снижает нагрузку на браузер, сохраняя корректность расчётов сцен.
requestAnimationFrameИногда применяют requestAnimationFrame,
чтобы синхронизировать пересчёт с циклом рендеринга браузера. Это
особенно полезно, если требуется плавная реакция на resize без лишних
просадок FPS.
let resizePending = false;
window.addEventListener("resize", function() {
if (!resizePending) {
resizePending = true;
requestAnimationFrame(function() {
controller.update();
resizePending = false;
});
}
});
Преимущества:
Для больших проектов полезно минимизировать работу ScrollMagic сцен на resize:
function updateSectionScenes(sectionController) {
sectionController.update();
}
window.addEventListener("resize", function() {
clearTimeout(resizeTimeout);
resizeTimeout = setTimeout(function() {
updateSectionScenes(controllerSection1);
updateSectionScenes(controllerSection2);
}, 250);
});
scene.refresh() –
пересчитывает размеры и позиции сцены с учётом изменившихся DOM
элементов:scene.refresh();
Это особенно важно при динамическом контенте, который может менять высоту блоков.
controller.update() на каждом
scroll или resize, если это не критично для
сцены.requestAnimationFrame для
максимальной производительности.let resizeTimeout;
let resizePending = false;
function optimizedResizeUpdate() {
if (!resizePending) {
resizePending = true;
requestAnimationFrame(function() {
scenes.forEach(scene => scene.refresh());
resizePending = false;
});
}
}
window.addEventListener("resize", function() {
clearTimeout(resizeTimeout);
resizeTimeout = setTimeout(optimizedResizeUpdate, 200);
});
Особенности подхода:
requestAnimationFrame.refresh().resize.Эффективная работа ScrollMagic при изменении размера окна напрямую
зависит от грамотного управления обновлением сцен и контроллера, а
сочетание debounce с requestAnimationFrame обеспечивает
высокую производительность даже на сложных страницах.