Lottie — Airbnbが開発したオープンソースライブラリで、Bodymovinプラグインを介してAdobe After EffectsからJSON形式にエクスポートされたベクターアニメーションをレンダリングします。アニメーションはプログラムによってレンダリングされ、どの画面解像度でも品質を損ないません。GitHub(2026年)によると、LottieはiOS、Android、Web上の50,000以上のプロジェクトで使用されています。他の種類のアニメーションについては、アニメーションの一般ガイドをご覧ください。
重要なポイント
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はプラットフォームの機能に適応する階層型レンダリングアーキテクチャを使用します。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。
| プラットフォーム | レンダラー | ハードウェアアクセラレーション | ライブラリ |
|---|---|---|---|
| Android | Canvas (LottieDrawable) | Hardware Accelerator (API 14+) | com.airbnb.lottie |
| iOS | Core Animation (CALayer) | GPU (Metal, OpenGL) | Lottie-iOS |
| Flutter | Skia Canvas (CustomPainter) | Impeller (Flutter 3.16+) | lottie_flutter |
| React Native | Native bridge | プラットフォームによる | lottie-react-native |
Androidでは、LottieAnimationViewはAppCompatImageViewを拡張し、ローディングとレンダリングの全サイクルを処理します。JSONファイルはres/rawまたはassetsフォルダに配置されます。LottieAnimationViewは再生制御 — play、pause、resume、setFrame、setProgress、repeat、speed — とAnimatorUpdateListenerおよびAnimatorListenerを介したリスニングをサポートしています。
<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" />
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では、AnimationViewがUIKitとSwiftUIのメインLottieクラスです。Swift Package ManagerまたはCocoaPodsを介して追加されます。JSONファイルはプロジェクトのバンドルに追加されます。AnimationViewは自動的にスケール(論理画面密度)を決定し、Core Animationを使用して60 FPSでレイヤーをレンダリングします。
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))
// 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は動画ファイルとは根本的に異なります:ピクセルを保存するのではなく、ベクターシェイプ、その変換、時間の経過に伴う変化のカーブを記述します。動画(MP4、WebM)は固定解像度のラスターフレームのシーケンスです。違いは、ファイルサイズ、拡大縮小の品質、インタラクティブ性、パフォーマンスに現れます。
| パラメータ | Lottie (JSON) | 動画 (MP4) | GIF |
|---|---|---|---|
| ファイルサイズ | 5~50 KB | 200~2000 KB | 500~5000 KB |
| 拡大縮小の品質 | ベクター(無限) | 固定(ピクセル) | 固定 |
| インタラクティブ性 | 進行、速度、一時停止、色の変更 | なし | なし |
| アルファチャンネル(透明度) | ネイティブ | コーデックが必要 | 対応 |
| パフォーマンス (CPU) | 低負荷 | 中程度(デコード) | 高(ラスターデコード) |
Lottieを選ぶべき時:ローディングアイコン、いいね/リアクションアニメーション、オンボーディング画面、ボタンのアクセントマイクロアニメーション。3Dエフェクト、リアルな照明、フォトリアリスティックなキャラクターを伴う複雑なシーンには、動画の方が実用的な選択肢です。Lottieは長いシーン(10秒以上)の再生用には設計されていません — 1つのアニメーションの最適な長さは2~5秒です。
Lottieのパフォーマンスは、レイヤー数、マスクとエフェクトの複雑さ、およびレンダラーに依存します。ミッドレンジデバイスで60 FPSを維持するには、次の推奨事項に従ってください:シーンごとのレイヤー数を30~40に制限し、重複するネストされたプリコンポジションを回避し、複雑なアニメーションにはdotLottieを使用します。
// 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%削減されます。
よくある質問
dotLottieを使用します — protobufベースのバイナリ形式で、JSONを50~80%圧縮します。After Effectsでは、「Glyphs」設定をNone(テキストが不要な場合)にしてBodymovinを介してエクスポートし、不要なガイドやガイドレイヤーを無効にします。エクスポート前に非表示のレイヤーと不透明度0%のレイヤーを削除します。
最小SDKバージョンを確認してください:Android用LottieはAPI 14+をサポートしていますが、一部のエフェクト(Path Morphing、Gradient)はAPI 21+でのみ動作します。iOSでは、LottieはiOS 11+が必要です。古いデバイスには、フォールバックとしてアニメーションの静的pngフレームを使用します。LottieCompositionFactoryを介してアニメーションを非同期に読み込み、LottieListener.onFailureでエラー処理を行います。
はい、LottieDynamicPropertiesまたはKeyPathを介して可能です。After Effectsでレイヤー名を設定し(例:「icon-fill」)、コードで:lottieView.addValueCallback(KeyPath("icon-fill"), LottieProperty.COLOR) { Color.GREEN }。これにより、重複ファイルを作成せずにアプリのテーマに合わせてアニメーションをカスタマイズできます。iOSの場合は、AnimationView.setValueProvider(ColorValueProvider)を使用します。
Lottie — After Effectsから事前に作成されたアニメーションを再生するためのフォーマット。Rive — ステートマシン、トリガー、入力を備えたインタラクティブアニメーション。Lottieはパッシブアニメーション(ローディング、いいね、ウェルカム画面)に適しています。Riveはゲーム、インタラクティブUI要素、ユーザーアクションへのフィードバックを伴うアニメーション向けです。Riveには独自のエディターが必要ですが、LottieはおなじみのAfter Effectsを通じて動作します。
Android:lottieView.addAnimatorListener(object : AnimatorListenerAdapter() { override fun onAnimationEnd(animation: Animator?) { ... } })。iOS:animationView.play { finished in }。SwiftUI:onChange付きのcurrentProgress用Bindingを使用。Kotlin Multiplatformの場合は、lottie-composeライブラリのLottieAnimatableを使用します。
まとめ
ターンキー方式のモバイルアプリケーションを開発します
IT Sectrは2017年からスタートアップや企業向けにiOS・Androidアプリケーションを開発しています。私たちがご相談に乗り、最適なソリューションをご提案します。