Lottie — nó là gì, hoạt ảnh vector trong ứng dụng di động

Tác giả: IT Sectr Đã đăng: 2026-03-01 Thời gian đọc: 10 phút

Lottie — thư viện mã nguồn mở của Airbnb giúp kết xuất hoạt ảnh vector được xuất từ Adobe After Effects sang định dạng JSON thông qua plugin Bodymovin. Hoạt ảnh được kết xuất theo chương trình mà không giảm chất lượng ở bất kỳ độ phân giải màn hình nào. Theo GitHub (2026), Lottie được sử dụng trong hơn 50.000 dự án trên iOS, Android và Web. Tìm hiểu thêm về các loại hoạt ảnh khác trong hướng dẫn chung về hoạt ảnh.

Những điểm chính

  • Lottie — thư viện Airbnb cho hoạt ảnh vector JSON từ After Effects.
  • Bodymovin — plugin xuất hoạt ảnh từ After Effects sang JSON.
  • LottieAnimationView — thành phần View chính cho Android (Kotlin/Java).
  • AnimationView — thành phần UI chính cho iOS (Swift, UIKit/SwiftUI).
  • Định dạng .lottie — vùng chứa nhị phân nén, giảm kích thước tới 80%.

Lottie là gì?

Lottie — thư viện đa nền tảng để phát hoạt ảnh vector, được phát triển tại Airbnb vào năm 2015. Nó giải quyết vấn đề về tệp video nặng và sprite sheet raster: nhà thiết kế tạo hoạt ảnh trong After Effects, xuất qua Bodymovin sang JSON và nhà phát triển nhúng tệp này vào ứng dụng di động. Lottie kết xuất hoạt ảnh theo chương trình qua Canvas, Core Animation hoặc Skia, tùy thuộc vào nền tảng.

Lợi thế chính của Lottie — hoạt ảnh vector co giãn không mất chất lượng trên mọi màn hình: từ Apple Watch đến TV 4K. Kích thước tệp JSON hoạt ảnh thường là 5–50 KB, nhỏ hơn hàng chục lần so với tệp video tương đương. Theo Airbnb Engineering (2025), Lottie hỗ trợ hơn 80% tính năng của Adobe After Effects, bao gồm mặt nạ, hiệu ứng, đường cong và biểu thức.

Bodymovin — là plugin cho After Effects (miễn phí, GitHub) tuần tự hóa bố cục thành định dạng JSON mà môi trường thực thi Lottie hiểu được. Hỗ trợ After Effects CC 2018 trở lên. Đối với hoạt ảnh phức tạp với nhiều khung hình chính, dotLottie được khuyến nghị — định dạng dựa trên Lottie JSON nhưng được nén và đóng gói thành một tệp duy nhất.

Kiến trúc Lottie: cách kết xuất hoạt động

Lottie sử dụng kiến trúc kết xuất theo lớp thích ứng với khả năng của nền tảng. Trên Android, hoạt ảnh được vẽ qua API Canvas — công cụ kết xuất riêng của Lottie (LottieDrawable), không sử dụng hoạt ảnh hệ thống. Trên iOS, Lottie dựa vào Core Animation Layers, mang lại hiệu suất cao và 60 FPS. Trên Flutter, Lottie sử dụng Skia Canvas qua CustomPainter.

Quá trình kết xuất trải qua ba giai đoạn: phân tích cú pháp JSON — phân tích hoạt ảnh thành LottieComposition (tất cả các lớp, hình dạng, khung hình chính); nội suy — tính toán giá trị trung gian giữa các khung hình chính có xét đến đường cong easing; vẽ — kết xuất khung hình hiện tại trên Canvas hoặc qua Core Animation. Lottie hỗ trợ tăng tốc phần cứng: trên Android — tăng tốc qua Canvas với Hardware Accelerator, trên iOS — CALayer với tăng tốc GPU tích hợp của Core Animation.

Nền tảngCông cụ kết xuấtTăng tốc phần cứngThư viện
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 bridgePhụ thuộc vào nền tảnglottie-react-native

Sử dụng Lottie trên Android (Kotlin)

Trên Android, LottieAnimationView mở rộng AppCompatImageView và xử lý toàn bộ chu trình tải và kết xuất. Tệp JSON được đặt trong thư mục res/raw hoặc assets. LottieAnimationView hỗ trợ điều khiển phát lại — play, pause, resume, setFrame, setProgress, repeat, speed — và lắng nghe qua AnimatorUpdateListener và 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

// Thiết lập lập trình 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()
}

// Tải từ assets và lưu vào bộ nhớ đệm
lottieView.setAnimation("animations/confetti.json")
lottieView.setCacheStrategy(LottieAnimationView.CacheStrategy.Strong)

// LottieDrawable — vẽ tùy chỉnh không cần View
val drawable = LottieDrawable().apply {
    setComposition(
        LottieCompositionFactory.fromRawRes(context, R.raw.star)
            .addListener { composition -> composition?.let { setComposition(it); play() } }
    )
}

Các phương pháp hay nhất cho Android: sử dụng setCacheStrategy(CacheStrategy.Strong) cho các hoạt ảnh lặp lại thường xuyên — bố cục được lưu vào bộ nhớ đệm và mỗi phiên bản mới không phân tích JSON lại. Đối với danh sách (RecyclerView), hãy sử dụng LottieAnimationView với enableMergePathsForKitKatAndAbove(true) và disableExtraScaleModeForOlderWorkarounds() để tối ưu kết xuất. Đối với hoạt ảnh có nền trong suốt, hãy đặt android:layerType="hardware" để tăng tốc GPU.

Sử dụng Lottie trên iOS (Swift)

Trên iOS, AnimationView là lớp Lottie chính cho UIKit và SwiftUI. Nó được thêm qua Swift Package Manager hoặc CocoaPods. Các tệp JSON được thêm vào gói dự án. AnimationView tự động xác định tỷ lệ (mật độ màn hình logic) và sử dụng Core Animation để kết xuất các lớp ở 60 FPS.

swift
import Lottie

// UIKit: AnimationView với điều khiển thủ công
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: hoạt ảnh với tiến trình (để gắn với sự kiện)
animationView.play(fromFrame: AnimationFrameTime(30),
                    toFrame: AnimationFrameTime(90))
swift
// SwiftUI: LottieView như UIViewRepresentable
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
    }
}

// Sử dụng trong SwiftUI
LottieView(name: "loading", progress: $animationProgress)
    .frame(width: 100, height: 100)

Các phương pháp hay nhất cho iOS: đối với hoạt ảnh bắt đầu ngay sau khi tải, hãy sử dụng animationView.play(fromProgress: 0, toProgress: 1) với loopMode = .playOnce cho các hiệu ứng nhấn mạnh một lần. Đối với Lottie trong UITableView/UICollectionView, hãy sử dụng AnimationView với tệp hoạt ảnh đã lưu trong bộ nhớ đệm qua LottieAnimation.cached. Kết xuất số lượng lớn lớp (50+) có thể gây giảm FPS — trong trường hợp đó, hãy bật renderingEngine = .mainThread (mặc định) hoặc .coreAnimation cho macOS.

Lottie so với video: so sánh định dạng hoạt ảnh

Lottie khác cơ bản so với tệp video: nó không lưu trữ pixel mà mô tả các hình dạng vector, phép biến đổi và đường cong thay đổi theo thời gian. Video (MP4, WebM) là một chuỗi các khung hình raster ở độ phân giải cố định. Sự khác biệt thể hiện ở kích thước tệp, chất lượng co giãn, tính tương tác và hiệu suất.

Tham sốLottie (JSON)Video (MP4)GIF
Kích thước tệp5–50 KB200–2000 KB500–5000 KB
Chất lượng co giãnVector (vô hạn)Cố định (pixel)Cố định
Tính tương tácTiến trình, tốc độ, tạm dừng, đổi màuKhôngKhông
Kênh alpha (độ trong suốt)GốcYêu cầu codecĐược hỗ trợ
Hiệu suất (CPU)Tải thấpTrung bình (giải mã)Cao (giải mã raster)

Khi nào chọn Lottie: biểu tượng tải, hoạt ảnh thích/lượt tương tác, màn hình giới thiệu, vi hoạt ảnh nhấn mạnh nút bấm. Đối với cảnh phức tạp có hiệu ứng 3D, ánh sáng thực tế hoặc nhân vật siêu thực, video vẫn là lựa chọn thực tế hơn. Lottie không được thiết kế để phát các cảnh dài (hơn 10 giây) — thời lượng tối ưu cho một hoạt ảnh là 2–5 giây.

Tối ưu hiệu suất Lottie

Hiệu suất Lottie phụ thuộc vào số lượng lớp, độ phức tạp của mặt nạ và hiệu ứng, cũng như công cụ kết xuất. Để duy trì 60 FPS trên các thiết bị tầm trung, hãy làm theo các khuyến nghị sau: giới hạn số lượng lớp ở mức 30–40 mỗi cảnh, tránh các bố cục trước lồng nhau chồng chéo, sử dụng dotLottie cho các hoạt ảnh phức tạp.

kotlin
// Tối ưu Lottie cho RecyclerView
import com.airbnb.lottie.LottieAnimationView
import com.airbnb.lottie.LottieDrawable
import com.airbnb.lottie.LottieCompositionFactory

// Lưu bố cục vào bộ nhớ đệm
private val cache = LottieCompositionFactory.setCacheStrategy(CacheStrategy.Strong)

// Nhóm LottieAnimationView để tái sử dụng
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)
    }
}

// Tắt các tính năng không cần thiết
lottieView.enableMergePathsForKitKatAndAbove(true)
lottieView.setHardwareAcceleration(true)
lottieView.setMaxFrame(60) // Giới hạn số khung hình

Tối ưu bổ sung: bật enableMergePathsForKitKatAndAbove(true) cho các thiết bị Android 4.4+ — tính năng này hợp nhất các đường dẫn chồng chéo thành một đường dẫn duy nhất, giảm số lần gọi vẽ. Sử dụng dotLottie thay vì JSON — định dạng nhị phân nén hoạt ảnh 50–80% thông qua tuần tự hóa protobuf, giảm thời gian phân tích. Đối với hoạt ảnh trong RecyclerView, đặt repeatCount = 0 (phát một lần) và dừng hoạt ảnh khi cuộn qua recyclerView.addOnScrollListener. Theo Airbnb Engineering Blog (2025), các biện pháp này giảm tải CPU tới 40%.

Câu hỏi thường gặp

Làm thế nào để giảm kích thước Lottie JSON?

Sử dụng dotLottie — định dạng nhị phân dựa trên protobuf nén JSON 50–80%. Trong After Effects, xuất qua Bodymovin với cài đặt "Glyphs" = None (nếu không cần văn bản), tắt các hướng dẫn và lớp hướng dẫn không cần thiết. Xóa các lớp không nhìn thấy và lớp có độ mờ 0% trước khi xuất.

Lottie không phát trên thiết bị cũ — phải làm gì?

Kiểm tra phiên bản SDK tối thiểu: Lottie cho Android hỗ trợ API 14+, nhưng một số hiệu ứng (Path Morphing, Gradient) chỉ hoạt động với API 21+. Trên iOS, Lottie yêu cầu iOS 11+. Đối với thiết bị cũ, hãy sử dụng phương án dự phòng — khung hình png tĩnh từ hoạt ảnh. Tải hoạt ảnh không đồng bộ qua LottieCompositionFactory với xử lý lỗi qua LottieListener.onFailure.

Có thể thay đổi màu sắc trong hoạt ảnh Lottie một cách động không?

Có, thông qua LottieDynamicProperties hoặc KeyPath. Đặt tên lớp trong After Effects (ví dụ: "icon-fill"), sau đó trong mã: lottieView.addValueCallback(KeyPath("icon-fill"), LottieProperty.COLOR) { Color.GREEN }. Điều này cho phép tùy chỉnh hoạt ảnh theo chủ đề ứng dụng mà không tạo tệp trùng lặp. Đối với iOS, sử dụng AnimationView.setValueProvider(ColorValueProvider).

Lottie so với Rive — sự khác biệt là gì?

Lottie — định dạng phát hoạt ảnh được tạo sẵn từ After Effects. Rive — hoạt ảnh tương tác với State Machine, trình kích hoạt và đầu vào. Lottie phù hợp cho hoạt ảnh thụ động (tải, thích, màn hình chào mừng). Rive dành cho trò chơi, phần tử UI tương tác, hoạt ảnh có phản hồi theo hành động của người dùng. Rive yêu cầu trình chỉnh sửa riêng, Lottie hoạt động thông qua After Effects quen thuộc.

Làm thế nào để theo dõi hoàn thành hoạt ảnh Lottie?

Trên Android: lottieView.addAnimatorListener(object : AnimatorListenerAdapter() { override fun onAnimationEnd(animation: Animator?) { ... } }). Trên iOS: animationView.play { finished in }. Trong SwiftUI: sử dụng Binding cho currentProgress với onChange. Đối với Kotlin Multiplatform, sử dụng LottieAnimatable từ thư viện lottie-compose.

Tổng kết

  • Lottie — thư viện Airbnb để phát hoạt ảnh vector JSON từ After Effects.
  • Bodymovin — plugin xuất After Effects → JSON, miễn phí, mã nguồn mở.
  • LottieAnimationView (Android) và AnimationView (iOS) — thành phần chính để nhúng.
  • Định dạng dotLottie (.lottie) giảm kích thước tệp tới 80% nhờ nén protobuf.
  • Lottie kết xuất qua Canvas (Android), Core Animation (iOS) hoặc Skia (Flutter) ở 60 FPS.
  • Thời lượng hoạt ảnh Lottie tối ưu là 2–5 giây, không quá 30–40 lớp mỗi cảnh.
  • Đối với hoạt ảnh tương tác có phản hồi, hãy sử dụng Rive thay vì Lottie.

Chúng tôi sẽ phát triển ứng dụng di động chìa khóa trao tay

IT Sectr tạo các ứng dụng iOS và Android cho các công ty khởi nghiệp và doanh nghiệp từ năm 2017. Chúng tôi sẽ tư vấn và đề xuất giải pháp tốt nhất cho bạn.

Thảo luận dự án

Đọc thêm