Lottie — 무엇인가, 모바일 앱에서 벡터 애니메이션

저자: IT Sectr 게시일: 2026-03-01 읽는 시간: 10 분

Lottie — Airbnb의 오픈소스 라이브러리로, Bodymovin 플러그인을 통해 Adobe After Effects에서 JSON 형식으로 내보낸 벡터 애니메이션을 렌더링합니다. 애니메이션은 프로그래밍 방식으로 렌더링되며 모든 화면 해상도에서 품질 저하가 없습니다. GitHub(2026)에 따르면 Lottie는 iOS, Android 및 웹에서 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 TV까지 모든 화면에서 품질 저하 없이 확장됩니다. 애니메이션 JSON 파일 크기는 일반적으로 5–50KB로, 동등한 비디오 파일보다 수십 배 작습니다. Airbnb Engineering(2025)에 따르면, Lottie는 마스크, 효과, 곡선 및 표현식을 포함하여 Adobe After Effects 기능의 80% 이상을 지원합니다.

Bodymovin — After Effects용 플러그인(무료, GitHub)으로, Lottie 런타임이 이해할 수 있는 JSON 형식으로 컴포지션을 직렬화합니다. After Effects CC 2018 이상을 지원합니다. 많은 키프레임이 있는 복잡한 애니메이션의 경우 dotLottie가 권장됩니다 — Lottie JSON을 기반으로 하지만 압축되어 단일 파일로 패키징된 형식입니다.

Lottie 아키텍처: 렌더링 작동 방식

Lottie는 플랫폼 기능에 적응하는 계층형 렌더링 아키텍처를 사용합니다. Android에서는 Canvas API를 통해 애니메이션이 그려집니다 — Lottie 자체 렌더러(LottieDrawable)로, 시스템 애니메이션을 사용하지 않습니다. iOS에서는 Lottie가 Core Animation Layers에 의존하여 높은 성능과 60FPS를 제공합니다. Flutter에서는 Lottie가 CustomPainter를 통해 Skia Canvas를 사용합니다.

렌더링은 세 단계를 거칩니다: 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을 사용하여 60FPS로 레이어를 렌더링합니다.

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 모범 사례: 로드 직후 시작되는 애니메이션의 경우 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–50KB200–2000KB500–5000KB
확대/축소 품질벡터(무한)고정(픽셀)고정
상호작용성진행, 속도, 일시정지, 색상 변경없음없음
알파 채널(투명도)네이티브코덱 필요지원
성능 (CPU)낮은 부하중간(디코딩)높음(래스터 디코딩)

Lottie를 선택해야 할 때: 로딩 아이콘, 좋아요/반응 애니메이션, 온보딩 화면, 버튼의 악센트 마이크로애니메이션. 3D 효과, 사실적인 조명 또는 포토리얼리스틱 캐릭터가 있는 복잡한 장면의 경우 비디오가 더 실용적인 선택입니다. Lottie는 긴 장면(10초 이상) 재생용으로 설계되지 않았습니다 — 하나의 애니메이션 최적 지속 시간은 2~5초입니다.

Lottie 성능 최적화

Lottie 성능은 레이어 수, 마스크 및 효과의 복잡성, 렌더러에 따라 달라집니다. 중간급 기기에서 60FPS를 유지하려면 다음 권장 사항을 따르세요: 장면당 레이어 수를 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)를 활성화하세요 — 중복 경로를 단일 경로로 병합하여 드로우 호출 수를 줄입니다. JSON 대신 dotLottie를 사용하세요 — 바이너리 형식이 protobuf 직렬화를 통해 애니메이션을 50~80% 압축하여 파싱 시간을 줄입니다. RecyclerView의 애니메이션에서는 repeatCount = 0(단일 재생)으로 설정하고 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 — State Machine, 트리거 및 입력이 있는 대화형 애니메이션입니다. 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)를 통해 60FPS로 렌더링합니다.
  • 최적의 Lottie 애니메이션 지속 시간은 2~5초, 장면당 레이어는 30~40개를 초과하지 않아야 합니다.
  • 피드백이 있는 대화형 애니메이션의 경우 Lottie 대신 Rive를 사용하세요.

턴키 방식의 모바일 애플리케이션을 개발해 드립니다

IT Sectr는 2017년부터 스타트업과 기업을 위한 iOS 및 Android 애플리케이션을 만듭니다. 저희가 상담해 드리고 최적의 솔루션을 제안하겠습니다.

프로젝트 논의

더 읽어보기