Lottie — とは何か、モバイルアプリにおけるベクターアニメーション

著者: IT Sectr 公開日: 2026-03-01 読了時間: 10 分

Lottie — Airbnbが開発したオープンソースライブラリで、Bodymovinプラグインを介してAdobe After EffectsからJSON形式にエクスポートされたベクターアニメーションをレンダリングします。アニメーションはプログラムによってレンダリングされ、どの画面解像度でも品質を損ないません。GitHub(2026年)によると、LottieはiOS、Android、Web上の50,000以上のプロジェクトで使用されています。他の種類のアニメーションについては、アニメーションの一般ガイドをご覧ください。

重要なポイント

  • Lottie — After EffectsからベクターアニメーションJSONを扱うAirbnbライブラリ。
  • Bodymovin — After EffectsからJSONにアニメーションをエクスポートするプラグイン。
  • LottieAnimationView — Android(Kotlin/Java)用のメインViewコンポーネント。
  • AnimationView — iOS(Swift、UIKit/SwiftUI)用のメインUIコンポーネント。
  • .lottie形式 — 圧縮バイナリコンテナ、サイズを最大80%削減。

Lottieとは?

Lottie — ベクターアニメーションを再生するためのクロスプラットフォームライブラリで、2015年にAirbnbで開発されました。重い動画ファイルやラスタースプライトシートの問題を解決します。デザイナーがAfter Effectsでアニメーションを作成し、Bodymovinを介してJSONにエクスポートし、開発者がこのファイルをモバイルアプリに埋め込みます。Lottieはプラットフォームに応じて、Canvas、Core Animation、またはSkiaを介してプログラムによってアニメーションをレンダリングします。

Lottieの主な利点 — ベクターアニメーションはApple Watchから4Kテレビまで、あらゆる画面で品質を損なうことなく拡大縮小できます。アニメーションJSONファイルのサイズは通常5~50KBで、同等の動画ファイルの数十分の一です。Airbnb Engineering(2025年)によると、Lottieはマスク、エフェクト、カーブ、エクスプレッションを含むAdobe After Effectsの機能の80%以上をサポートしています。

Bodymovin — After Effects用のプラグイン(無料、GitHub)で、Lottieランタイムが理解できるJSON形式にコンポジションをシリアライズします。After Effects CC 2018以降をサポートしています。多数のキーフレームを持つ複雑なアニメーションには、dotLottieが推奨されます — Lottie JSONをベースにしていますが、圧縮されて1つのファイルにパッケージ化された形式です。

Lottieのアーキテクチャ:レンダリングの仕組み

Lottieはプラットフォームの機能に適応する階層型レンダリングアーキテクチャを使用します。Androidでは、アニメーションはCanvas APIを介して描画されます — Lottie独自のレンダラー(LottieDrawable)で、システムアニメーションは使用しません。iOSでは、LottieはCore Animation Layersに依存し、高いパフォーマンスと60 FPSを提供します。Flutterでは、LottieはCustomPainterを介してSkia Canvasを使用します。

レンダリングは3つの段階を経ます:JSON解析 — アニメーションをLottieComposition(すべてのレイヤー、シェイプ、キーフレーム)に解析;補間 — イージングカーブを考慮したキーフレーム間の中間値の計算;描画 — Canvas上またはCore Animationを介した現在のフレームのレンダリング。Lottieはハードウェアアクセラレーションをサポート:AndroidではHardware Acceleratorを使用したCanvasによるアクセラレーション、iOSではCore Animationの内蔵GPUアクセラレーションを備えたCALayer。

プラットフォームレンダラーハードウェアアクセラレーションライブラリ
AndroidCanvas (LottieDrawable)Hardware Accelerator (API 14+)com.airbnb.lottie
iOSCore Animation (CALayer)GPU (Metal, OpenGL)Lottie-iOS
FlutterSkia Canvas (CustomPainter)Impeller (Flutter 3.16+)lottie_flutter
React NativeNative bridgeプラットフォームによるlottie-react-native

Android(Kotlin)でのLottieの使用

Androidでは、LottieAnimationViewはAppCompatImageViewを拡張し、ローディングとレンダリングの全サイクルを処理します。JSONファイルはres/rawまたはassetsフォルダに配置されます。LottieAnimationViewは再生制御 — play、pause、resume、setFrame、setProgress、repeat、speed — とAnimatorUpdateListenerおよびAnimatorListenerを介したリスニングをサポートしています。

xml

<com.airbnb.lottie.LottieAnimationView
    android:id="@+id/animationView"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    app:lottie_rawRes="@raw/loading_animation"
    app:lottie_autoPlay="true"
    app:lottie_loop="true" />
kotlin
import com.airbnb.lottie.LottieAnimationView
import com.airbnb.lottie.LottieListener

// LottieAnimationViewのプログラムによる設定
val lottieView = LottieAnimationView(context).apply {
    setAnimation(R.raw.celebrate_animation)
    repeatCount = ValueAnimator.INFINITE
    speed = 1.5f
    addAnimatorUpdateListener { animator ->
        val progress = animator.animatedValue as Float
        progressBar.progress = (progress * 100).toInt()
    }
    playAnimation()
}

// assetsからの読み込みとキャッシュ
lottieView.setAnimation("animations/confetti.json")
lottieView.setCacheStrategy(LottieAnimationView.CacheStrategy.Strong)

// LottieDrawable — Viewなしのカスタム描画
val drawable = LottieDrawable().apply {
    setComposition(
        LottieCompositionFactory.fromRawRes(context, R.raw.star)
            .addListener { composition -> composition?.let { setComposition(it); play() } }
    )
}

Androidのベストプラクティス:頻繁に繰り返されるアニメーションにはsetCacheStrategy(CacheStrategy.Strong)を使用します — コンポジションがメモリにキャッシュされ、新しいインスタンスごとにJSONを再解析しません。リスト(RecyclerView)の場合は、enableMergePathsForKitKatAndAbove(true)とdisableExtraScaleModeForOlderWorkarounds()を有効にしたLottieAnimationViewを使用してレンダリングを最適化します。透明な背景のアニメーションの場合は、GPUアクセラレーションのためにandroid:layerType="hardware"を設定します。

iOS(Swift)でのLottieの使用

iOSでは、AnimationViewがUIKitとSwiftUIのメインLottieクラスです。Swift Package ManagerまたはCocoaPodsを介して追加されます。JSONファイルはプロジェクトのバンドルに追加されます。AnimationViewは自動的にスケール(論理画面密度)を決定し、Core Animationを使用して60 FPSでレイヤーをレンダリングします。

swift
import Lottie

// UIKit: 手動制御のAnimationView
let animationView = AnimationView(name: "confetti")
animationView.frame = view.bounds
animationView.contentMode = .scaleAspectFit
animationView.loopMode = .loop
animationView.animationSpeed = 1.5
animationView.play(fromProgress: 0, toProgress: 0.5) { finished in
    print("Animation segment finished: \(finished)")
}
view.addSubview(animationView)

// UIKit: 進捗付きアニメーション(イベントへのバインド用)
animationView.play(fromFrame: AnimationFrameTime(30),
                    toFrame: AnimationFrameTime(90))
swift
// SwiftUI: UIViewRepresentableとしてのLottieView
import Lottie
import SwiftUI

struct LottieView: UIViewRepresentable {
    let name: String
    var loopMode: LottieLoopMode = .loop
    @Binding var progress: CGFloat

    func makeUIView(context: Context) -> AnimationView {
        let view = AnimationView(name: name)
        view.contentMode = .scaleAspectFit
        view.loopMode = loopMode
        return view
    }

    func updateUIView(_ uiView: AnimationView, context: Context) {
        uiView.currentProgress = progress
    }
}

// SwiftUIでの使用
LottieView(name: "loading", progress: $animationProgress)
    .frame(width: 100, height: 100)

iOSのベストプラクティス:ロード直後に開始するアニメーションには、1回限りのアクセント効果としてloopMode = .playOnceを指定したanimationView.play(fromProgress: 0, toProgress: 1)を使用します。UITableView/UICollectionViewでLottieを使用する場合は、LottieAnimation.cachedを介してキャッシュされたアニメーションファイルを持つAnimationViewを使用します。多数のレイヤー(50以上)をレンダリングするとFPSが低下する可能性があります — そのような場合は、macOSではrenderingEngine = .mainThread(デフォルト)または.coreAnimationを有効にします。

Lottie vs 動画:アニメーションフォーマットの比較

Lottieは動画ファイルとは根本的に異なります:ピクセルを保存するのではなく、ベクターシェイプ、その変換、時間の経過に伴う変化のカーブを記述します。動画(MP4、WebM)は固定解像度のラスターフレームのシーケンスです。違いは、ファイルサイズ、拡大縮小の品質、インタラクティブ性、パフォーマンスに現れます。

パラメータLottie (JSON)動画 (MP4)GIF
ファイルサイズ5~50 KB200~2000 KB500~5000 KB
拡大縮小の品質ベクター(無限)固定(ピクセル)固定
インタラクティブ性進行、速度、一時停止、色の変更なしなし
アルファチャンネル(透明度)ネイティブコーデックが必要対応
パフォーマンス (CPU)低負荷中程度(デコード)高(ラスターデコード)

Lottieを選ぶべき時:ローディングアイコン、いいね/リアクションアニメーション、オンボーディング画面、ボタンのアクセントマイクロアニメーション。3Dエフェクト、リアルな照明、フォトリアリスティックなキャラクターを伴う複雑なシーンには、動画の方が実用的な選択肢です。Lottieは長いシーン(10秒以上)の再生用には設計されていません — 1つのアニメーションの最適な長さは2~5秒です。

Lottieパフォーマンスの最適化

Lottieのパフォーマンスは、レイヤー数、マスクとエフェクトの複雑さ、およびレンダラーに依存します。ミッドレンジデバイスで60 FPSを維持するには、次の推奨事項に従ってください:シーンごとのレイヤー数を30~40に制限し、重複するネストされたプリコンポジションを回避し、複雑なアニメーションにはdotLottieを使用します。

kotlin
// RecyclerView向けLottieの最適化
import com.airbnb.lottie.LottieAnimationView
import com.airbnb.lottie.LottieDrawable
import com.airbnb.lottie.LottieCompositionFactory

// メモリ内のコンポジションキャッシュ
private val cache = LottieCompositionFactory.setCacheStrategy(CacheStrategy.Strong)

// 再利用のためのLottieAnimationViewプール
class LottiePool {
    private val pool = LinkedList<LottieAnimationView>()

    fun acquire(context: Context): LottieAnimationView {
        return pool.poll() ?: LottieAnimationView(context)
    }

    fun release(view: LottieAnimationView) {
        view.pauseAnimation()
        view.cancelAnimation()
        pool.add(view)
    }
}

// 不要な機能の無効化
lottieView.enableMergePathsForKitKatAndAbove(true)
lottieView.setHardwareAcceleration(true)
lottieView.setMaxFrame(60) // フレーム数の制限

追加の最適化:Android 4.4+のデバイスではenableMergePathsForKitKatAndAbove(true)を有効にします — これにより重複するパスが1つのパスにマージされ、ドローコールの数が減少します。JSONの代わりにdotLottieを使用します — バイナリ形式はprotobufシリアライゼーションによりアニメーションを50~80%圧縮し、解析時間を短縮します。RecyclerViewのアニメーションでは、repeatCount = 0(1回再生)に設定し、recyclerView.addOnScrollListenerを介してスクロール時にアニメーションを停止します。Airbnb Engineering Blog(2025年)によると、これらの対策によりCPU負荷が最大40%削減されます。

よくある質問

Lottie JSONのサイズを減らすには?

dotLottieを使用します — protobufベースのバイナリ形式で、JSONを50~80%圧縮します。After Effectsでは、「Glyphs」設定をNone(テキストが不要な場合)にしてBodymovinを介してエクスポートし、不要なガイドやガイドレイヤーを無効にします。エクスポート前に非表示のレイヤーと不透明度0%のレイヤーを削除します。

Lottieが古いデバイスで再生されない — どうすれば?

最小SDKバージョンを確認してください:Android用LottieはAPI 14+をサポートしていますが、一部のエフェクト(Path Morphing、Gradient)はAPI 21+でのみ動作します。iOSでは、LottieはiOS 11+が必要です。古いデバイスには、フォールバックとしてアニメーションの静的pngフレームを使用します。LottieCompositionFactoryを介してアニメーションを非同期に読み込み、LottieListener.onFailureでエラー処理を行います。

Lottieアニメーションの色を動的に変更できますか?

はい、LottieDynamicPropertiesまたはKeyPathを介して可能です。After Effectsでレイヤー名を設定し(例:「icon-fill」)、コードで:lottieView.addValueCallback(KeyPath("icon-fill"), LottieProperty.COLOR) { Color.GREEN }。これにより、重複ファイルを作成せずにアプリのテーマに合わせてアニメーションをカスタマイズできます。iOSの場合は、AnimationView.setValueProvider(ColorValueProvider)を使用します。

Lottie vs Rive — 違いは?

Lottie — After Effectsから事前に作成されたアニメーションを再生するためのフォーマット。Rive — ステートマシン、トリガー、入力を備えたインタラクティブアニメーション。Lottieはパッシブアニメーション(ローディング、いいね、ウェルカム画面)に適しています。Riveはゲーム、インタラクティブUI要素、ユーザーアクションへのフィードバックを伴うアニメーション向けです。Riveには独自のエディターが必要ですが、LottieはおなじみのAfter Effectsを通じて動作します。

Lottieアニメーションの完了を追跡するには?

Android:lottieView.addAnimatorListener(object : AnimatorListenerAdapter() { override fun onAnimationEnd(animation: Animator?) { ... } })。iOS:animationView.play { finished in }。SwiftUI:onChange付きのcurrentProgress用Bindingを使用。Kotlin Multiplatformの場合は、lottie-composeライブラリのLottieAnimatableを使用します。

まとめ

  • Lottie — After EffectsからベクターアニメーションJSONを再生するためのAirbnbライブラリ。
  • Bodymovin — After Effects → JSONエクスポートプラグイン、無料、オープンソース。
  • LottieAnimationView(Android)とAnimationView(iOS) — 埋め込み用のメインコンポーネント。
  • dotLottie (.lottie)形式はprotobuf圧縮によりファイルサイズを最大80%削減。
  • LottieはCanvas(Android)、Core Animation(iOS)、またはSkia(Flutter)を介して60 FPSでレンダリング。
  • 最適なLottieアニメーションの長さは2~5秒、シーンあたり30~40レイヤーまで。
  • フィードバックを伴うインタラクティブアニメーションには、LottieではなくRiveを使用。

ターンキー方式のモバイルアプリケーションを開発します

IT Sectrは2017年からスタートアップや企業向けにiOS・Androidアプリケーションを開発しています。私たちがご相談に乗り、最適なソリューションをご提案します。

プロジェクトについて相談

こちらもお読みください