Про анимации появления спорят одинаково: одни считают, что они оживляют страницу, другие — что мешают. Мы этот спор у себя закрыли замером, и результат оказался хуже любой из позиций: анимация прятала текст, который посетитель уже читал.
Что происходило
На статическом сайте — а наш собран заранее, страницами — порядок такой. Браузер получает готовый HTML и рисует текст. JavaScript доезжает позже. И только после него оживают компоненты, которые «показывают» страницу.
Показывать уже нечего: страница видна. Поэтому анимация с начальным состоянием «прозрачность 0» даёт не появление, а исчезновение.
Замер живого сайта на канале 1,6 Мбит/с, страница города:
| Время | Что видит посетитель |
|---|---|
| 1500 мс | текст отрисован, читается |
| 3000 мс | вся обёртка уходит в прозрачность 0 |
| 3300–3600 мс | поверх идёт тёмная штора |
| 4000 мс | содержимое возвращается |
Две с половиной секунды человек смотрит, как исчезает то, что он начал читать. На быстром соединении этого не видно — все события укладываются в первые полсекунды, и глазами дефект не поймать. Именно поэтому спор и был спором: у каждого свой канал и своя правота.
Побочный эффект, из-за которого мы сами себя обманули
Пока страница прозрачна, браузер не засчитывает поздних кандидатов на главную отрисовку. Метрика LCP от этого выглядит лучше.
После того как анимацию убрали с первого захода, LCP «вырос» с 1700 до 2900 мс. Это не откат оптимизации — это снятие маскировки. Показатель улучшался ровно за счёт того, что текст прятали от посетителя, и мы едва не приняли маскировку за достижение. Мы уже ошибались с замером скорости — в тот раз из-за локального сервера без сжатия.
Как починили
Удалять анимацию целиком не стали. Разрыв, который она закрывает, бывает настоящим — при переходе по внутренней ссылке. Поэтому до первого перехода содержимое отдаётся как есть, а дальше анимация работает по-прежнему.
Заодно вышла экономия: раз до перехода анимация не нужна, её код подгружается отдельным куском и только при первом признаке, что посетитель собирается нажать. Библиотека перестала приходить на страницы, открытые из поиска: набор скриптов на странице города похудел с 832 до 708 КБ.
Замер сегодня
Проверили 3 сентября 2026 года на живом сайте — с настройкой
prefers-reduced-motion и без неё:
| Страница | LCP как обычно | LCP без анимаций |
|---|---|---|
| Главная | 348 мс | 236 мс |
| /seo/avtoservis/ | 200 мс | 180 мс |
| /ekaterinburg/ | 152 мс | 240 мс |
| /proverka/ | 192 мс | 228 мс |
Разница в обе стороны и в пределах десятков миллисекунд — то есть на первом заходе анимации больше ничего не прячут. Раньше расхождение между этими двумя колонками и было ценой анимаций.
Чего мы не доделали
Настройка операционной системы «меньше движения» у нас уважается только наполовину, и это видно по тому же замеру. В стилях стоит правило, которое сводит длительность анимаций к 0,01 мс, — но действует оно на CSS-анимации. Переход между страницами рисует JavaScript, и под это правило он не попадает.
Штора при переходе, три прогона на каждом режиме:
| Режим | Штора на экране |
|---|---|
| Как обычно | 584, 575, 584 мс |
| С prefers-reduced-motion | 542, 552, 509 мс |
Разница около семи процентов — это погрешность, а не уважение к настройке. Человек, который попросил систему убрать движение, всё равно получает полсекунды шторы. Недочёт открытый, заведён в работу; рассказываем о нём здесь, потому что юзабилити начинается с честного списка того, что не сделано.
Что забрать себе
- Ищите начальную прозрачность 0 в каркасе. Компонент, который монтируется
через
useEffectи стартует с прозрачности, на предрендеренной странице работает наоборот. - Мерьте на медленном канале и по времени. Дефект существует только там, где JavaScript отстаёт от HTML на секунды.
- Не радуйтесь улучшению LCP, если что-то скрыли. Проверяйте показатель в двух режимах: расхождение и есть цена анимации.
- Проверяйте, кто рисует движение. Правило в CSS не остановит анимацию из JavaScript — библиотеке настройку нужно передать отдельно.
Про то, почему у молодого домена вообще нет данных о настоящих посетителях, мы писали отдельно: Core Web Vitals по нам пусты, а трафик оказался роботами. Тем важнее лабораторные замеры делать честно.
