G-FORCE
0.0G
разгон
← все разборы

Красивые анимации, которые убивали телефоны


! Проблема

Для этого портфолио я хотел плотный визуал: летящие частицы, параллакс, появление блоков. На разработческой машине всё летало. Открыл на телефоне — прокрутка рывками, вентилятор ноутбука в соседней вкладке, батарея тает.

Решение

Переписал анимации так, чтобы браузер не пересчитывал раскладку: только transform и opacity, никаких top/left/width. Появление блоков перевёл с обработчика скролла на IntersectionObserver. Число частиц привязал к площади экрана с жёстким потолком, отрисовку останавливаю, когда вкладка неактивна. Добавил поддержку prefers-reduced-motion — кому тяжело от движения, тот его не увидит.

Как я к этому пришёл

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

Первая — обработчик скролла. Он выполнялся на каждое событие, а браузер шлёт их десятками в секунду. Внутри я читал getBoundingClientRect, и каждое такое чтение заставляло браузер пересчитывать раскладку страницы. IntersectionObserver делает то же самое, но силами самого браузера и без блокировки главного потока.

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

Третья — частицы. Я поставил фиксированное число, посчитанное для своего экрана. На телефоне столько же точек с попарным соединением линиями давало квадратичный рост вычислений. Привязал количество к площади и поставил потолок.

И отдельно: вкладка в фоне продолжала рисовать. Одна подписка на visibilitychange — и в фоне не тратится ни кадра.

Сайт остаётся плавным на среднем телефоне, батарея не греется, а при системной настройке «уменьшить движение» анимации просто выключаются.

Вывод

Плотный визуал и производительность не конфликтуют — конфликтуют визуал и невнимательность к тому, что именно ты анимируешь.

Другие разборы