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 đ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.
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ảng | Công cụ kết xuất | Tăng tốc phần cứng | Thư viện |
|---|---|---|---|
| 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 | Phụ thuộc vào nền tảng | lottie-react-native |
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.
<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
// 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.
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.
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))
// 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 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ệp | 5–50 KB | 200–2000 KB | 500–5000 KB |
| Chất lượng co giãn | Vector (vô hạn) | Cố định (pixel) | Cố định |
| Tính tương tác | Tiến trình, tốc độ, tạm dừng, đổi màu | Không | Không |
| Kênh alpha (độ trong suốt) | Gốc | Yêu cầu codec | Được hỗ trợ |
| Hiệu suất (CPU) | Tải thấp | Trung 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.
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.
// 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
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.
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ô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 — đị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.
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
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.
Đọc thêm