~/wiki / motion-i-animatsiya / lottie-animatsii-dlya-prodakshena

Lottie: как отправить анимацию в продакшен без боли и потери качества

Основной чат

Чат для вайбкодеров: новости, гайды, поиск исполнителей, маркетплейс и разбор реальных кейсов.

$ cd раздел/ $ join vibe dev
Lottie: как отправить анимацию в продакшен без боли и потери качества - обложка

Что такое dotLottie и почему это уже стандарт

В 2026 году есть два формата: старый .json и новый .lottie (dotLottie). Если ты ещё работаешь с .json — пора переходить.

.lottie — это ZIP-архив который упаковывает анимацию, ассеты и метаданные в один файл. По сравнению с .json:

  • Размер меньше на 50–80%
  • Поддержка нескольких анимаций в одном файле
  • Встроенные темы и слоты для динамической подмены цветов
  • State Machines для интерактивности (аналог Rive, но проще)
  • Один файл работает на вебе, iOS и Android без конвертации

Старый @lottiefiles/react-lottie-player задепрецирован и больше не обновляется. Новый официальный пакет — @lottiefiles/dotlottie-react. Он читает оба формата — и .json, и .lottie.


Часть 1: что должен сделать дизайнер перед экспортом

Большинство проблем с Lottie в продакшене закладываются на этапе анимации в After Effects. Не при экспорте и не при интеграции — именно там.

Называй слои понятно

Lottie экспортирует структуру слоёв напрямую в JSON. Слои с именами «Layer 1», «Shape 47», «Comp 3» превращаются в нечитаемый JSON который невозможно отлаживать. Разработчик не может найти нужный элемент, редактирование цвета программно — невозможно.

Правило: каждый смысловой элемент — отдельный именованный слой. «astronaut-body», «left-planet», «background-gradient» — не «Shape 12».

Избегай неподдерживаемых эффектов

Lottie не поддерживает всё что умеет After Effects. Проблемные техники:

Не работают или работают плохо: 3D-слои, размытие по Гауссу (Gaussian Blur) как самостоятельный эффект, некоторые blending modes, expressions с внешними зависимостями, плагины третьих сторон.

Работают: Shape Layers, Masks, Track Mattes, большинство стандартных эффектов AE, Trim Paths, Repeater, Gradient Fill.

Перед финальным экспортом — запускай Lottie Feature Checker прямо в плагине LottieFiles for After Effects. Он покажет что не поддерживается на каждой платформе.

Оптимальные настройки

  • FPS: 30 кадров/сек для большинства UI-анимаций. 24 для кинематографичных. 60 только если анимация критична к плавности и файл небольшой.
  • Размер композиции: такой же как итоговый размер на экране или чуть больше. Lottie масштабируется, но экспортировать 1000×1000 если нужно 200×200 — лишний вес.
  • Продолжительность: только то что нужно. Лишние секунды пустоты в начале и конце — это лишние килобайты.

Экспортируй через LottieFiles for After Effects, не через Bodymovin

Плагин LottieFiles — это обновлённый Bodymovin с дополнительными фичами: предпросмотр на разных устройствах прямо в AE, Feature Checker, экспорт сразу в .lottie (dotLottie), загрузка в воркспейс команды.

Bodymovin до сих пор работает, но экспортирует только .json без оптимизации.


Часть 2: оптимизация файла

Даже хорошо сделанная анимация после экспорта может весить слишком много. Три инструмента которые решают это без потери качества.

LottieFiles Optimizer

Встроен в платформу LottieFiles — загружаешь файл, получаешь оптимизированную версию. Убирает лишние данные, округляет координаты до нужной точности, сжимает. Обычно даёт 20–40% от .json без визуальных изменений.

dotLottie конвертация

Если ещё работаешь с .json — сконвертируй в .lottie. На платформе LottieFiles это один клик. Экономия 50–80% без потери качества — за счёт ZIP-компрессии.

Lottie Compress (опенсорс)

CLI-инструмент для батч-оптимизации:

bash
npx lottie-compress input.json -o output.json --quality 80

Полезен когда нужно автоматизировать оптимизацию в CI/CD.


Часть 3: интеграция в React

Установка

bash
npm install @lottiefiles/dotlottie-react

Не устанавливай задепрецированный @lottiefiles/react-lottie-player — он больше не обновляется.

Базовое использование

javascript
import { DotLottieReact } from "@lottiefiles/dotlottie-react"

export function LoadingSpinner() {
  return (
    <DotLottieReact
      src="/animations/spinner.lottie"
      loop
      autoplay
      style={{ width: 80, height: 80 }}
    />
  )
}

Компонент принимает .lottie и .json в пропе src — оба формата работают без изменений кода.

Программное управление воспроизведением

javascript
import { useRef } from "react"
import { DotLottieReact } from "@lottiefiles/dotlottie-react"

export function SuccessAnimation({ onComplete }) {
  const lottieRef = useRef(null)

  return (
    <DotLottieReact
      src="/animations/success.lottie"
      autoplay={false}         // не запускать автоматически
      loop={false}
      dotLottieRefCallback={(instance) => {
        lottieRef.current = instance
      }}
      onComplete={onComplete}   // колбэк по завершении
    />
  )
}

// Запуск из родителя
function Form() {
  const animRef = useRef(null)

  async function handleSubmit() {
    await submitForm()
    animRef.current?.play()
  }
}

Ленивая загрузка

Анимации не должны блокировать первый рендер страницы. Загружай компонент лениво:

javascript
import { lazy, Suspense } from "react"

const DotLottieReact = lazy(() =>
  import("@lottiefiles/dotlottie-react").then(m => ({
    default: m.DotLottieReact
  }))
)

export function HeroAnimation() {
  return (
    <Suspense fallback={<div style={{ width: 200, height: 200 }} />}>
      <DotLottieReact
        src="/animations/hero.lottie"
        loop
        autoplay
      />
    </Suspense>
  )
}

fallback с фиксированными размерами — чтобы не было layout shift при загрузке.

Три типовых компонента для продакшена

Loading, Success и Empty — самые частые задачи. Оформляй их как отдельные компоненты сразу:

javascript
// components/animations/index.jsx
import { DotLottieReact } from "@lottiefiles/dotlottie-react"

export function LoadingState({ size = 80 }) {
  return (
    <DotLottieReact
      src="/animations/loading.lottie"
      loop autoplay
      style={{ width: size, height: size }}
    />
  )
}

export function SuccessState({ size = 120, onComplete }) {
  return (
    <DotLottieReact
      src="/animations/success.lottie"
      loop={false} autoplay
      style={{ width: size, height: size }}
      onComplete={onComplete}
    />
  )
}

export function EmptyState({ size = 160 }) {
  return (
    <DotLottieReact
      src="/animations/empty.lottie"
      loop autoplay
      style={{ width: size, height: size }}
    />
  )
}

Хендофф через LottieFiles + Figma Dev Mode

Если команда работает в Figma, хендофф Lottie-анимаций идёт через плагин LottieFiles for Figma и Dev Mode — без отдельных файлов в Slack и папок в Dropbox.

Для дизайнера: плагин LottieFiles for Figma позволяет конвертировать анимированные Figma-компоненты напрямую в Lottie без After Effects. Подходит для простых UI-анимаций: иконки с состояниями, индикаторы загрузки, простые переходы. Для сложных анимаций всё равно нужен After Effects.

Для разработчика: в Figma Dev Mode рядом с компонентом появляется секция LottieFiles. Там embed-код, ссылка на CDN и код для подключения. Копируешь src и вставляешь в компонент — никаких скачиваний файлов вручную.

Пример с CDN-ссылкой:

javascript
// Ссылку берёшь прямо из Figma Dev Mode
<DotLottieReact
  src="https://lottie.host/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/file.lottie"
  loop
  autoplay
  style={{ width: 120, height: 120 }}
/>

CDN LottieFiles даёт кэширование и оптимизированную доставку. Для продакшен-проектов лучше всё равно хранить файлы у себя (/public/animations/) — меньше зависимость от внешнего сервиса.


Часть 4: распространённые проблемы и их решения

Анимация рендерится не так как в After Effects. Причина почти всегда — неподдерживаемый эффект AE. Запусти Feature Checker, найди красные пункты, перепроверь с дизайнером.

Файл слишком большой. Сначала конвертируй в .lottie, потом прогони через Optimizer. Если всё равно много — попроси дизайнера упростить количество одновременно анимируемых свойств.

Анимация дёргается или тормозит. Проверь useSubFrames — по умолчанию true, анимация обновляется на каждый requestAnimationFrame. Если это лишнее (анимация на 30fps, экран на 60fps) — поставь useSubFrames={false}:

javascript
<DotLottieReact src="animation.lottie" useSubFrames={false} />

Layout shift при загрузке. Всегда указывай размеры через style или CSS — иначе контейнер схлопнется до 0 пока файл грузится и подпрыгнет когда загрузится.


Промпты для агентов

Создать три базовых Lottie-компонента:

markdown
Установи @lottiefiles/dotlottie-react (не react-lottie-player — он задепрецирован).

Создай три компонента в /components/animations/:
- LoadingState — loop: true, autoplay: true, размер через size проп (default 80)
- SuccessState — loop: false, autoplay: true, onComplete колбэк, default size 120
- EmptyState — loop: true, autoplay: true, default size 160

Файлы анимаций в /public/animations/: loading.lottie, success.lottie, empty.lottie.
Каждый компонент должен иметь явно заданные width/height чтобы избежать layout shift.
Экспортируй именованными экспортами из index.jsx.

Добавить анимированный success после отправки формы:

markdown
В форме /components/ContactForm.jsx добавь:
- После успешной отправки показывать SuccessAnimation вместо формы
- Анимация: /public/animations/success.lottie, однократная, loop: false
- После завершения анимации (onComplete) через 1 секунду сбросить
  форму и показать её снова
- Пока анимация не загрузилась — показывать skeleton того же размера (200x200)
- Использовать @lottiefiles/dotlottie-react

Чеклист дизайнера перед передачей файла

plaintext
Подготовка в After Effects
☐ Все слои названы осмысленно, нет «Layer 1», «Shape 47»
☐ Нет Merge Paths которые ломают JSON-структуру
☐ Нет неподдерживаемых эффектов (проверено Feature Checker)
☐ FPS = 30, размер композиции = итоговый размер элемента
☐ Нет лишних секунд пустоты в начале и конце

Экспорт
☐ Плагин LottieFiles for After Effects, не Bodymovin
☐ Формат: dotLottie (.lottie), не JSON
☐ Прогнано через LottieFiles Optimizer

Передача разработчику
☐ Файл загружен в общий воркспейс LottieFiles
☐ Указаны нужные размеры и режим воспроизведения (loop/once)
☐ Проверено в предпросмотре на мобильном
$ cd ../ ← назад к Motion и анимация