Lottie adalah animasi yang disimpan sebagai data JSON: bentuk, warna, dan nilai tiap keyframe, diekspor dari Adobe After Effects lewat plugin Bodymovin. Di browser, sebuah pemutar (player) JavaScript membaca data itu dan menggambar ulang setiap frame ke SVG atau canvas. Bayangin bedanya rekaman lagu dan partitur. GIF atau video itu rekaman: piksel jadi yang tinggal diputar. Lottie itu partitur: catatan yang harus dimainkan seorang pemain di setiap frame. Hasilnya tajam di ukuran berapa pun, tapi selalu ada yang harus bekerja memainkannya.
🧪 Tebakan cepat: Check-mark di toast "Pesanan terkirim" bisa dibuat sebagai Lottie atau sebagai SVG plus CSS. Berapa byte yang harus diunduh versi Lottie dibanding versi SVG + CSS? Jawabannya ada di bagian "Biayanya: ukuran dan CPU".
Isi file Lottie
Ini check-mark Bu Sri sebagai Lottie, yang kami tulis tangan (1.634 byte). Bagian pentingnya:
{
"v": "5.12.2", "fr": 30, "ip": 0, "op": 60, "w": 48, "h": 48,
"layers": [
{ "ty": 4, "nm": "cek", "shapes": [
{ "ty": "gr", "it": [
{ "ty": "sh", "ks": { "k": { "v": [[15, 24.5], [21.5, 31], [33, 18]] } } },
{ "ty": "st", "c": { "k": [0.082, 0.502, 0.239, 1] }, "w": { "k": 3 } }
] },
{ "ty": "tm", "e": { "a": 1, "k": [ { "t": 6, "s": [0] }, { "t": 15, "s": [100] } ] } }
] }
]
}
| Kunci | Artinya |
|---|---|
v |
versi Bodymovin yang mengekspornya |
fr |
frame rate: 30 frame per detik |
ip, op |
frame awal dan akhir: 0 sampai 60 |
w, h |
ukuran kanvasnya, 48 × 48 |
layers |
lapisan; ty: 4 = shape layer |
sh, el |
bentuk: path (v = titik-titiknya) dan elips |
st |
stroke; warnanya RGBA 0 sampai 1, jadi #15803d = [0.082, 0.502, 0.239, 1] |
tm |
trim path: berapa persen garis yang tergambar; e beranimasi dari 0 ke 100 |
"a": 1, "k": [...] |
nilai beranimasi: keyframe di frame t dengan nilai s |
Durasinya (op - ip) / fr detik: 60 / 30 = 2 detik = 2.000 ms. Frame-nya dihitung dari 0, jadi frame terakhir adalah 59, bukan 60. Progress di frame 30 = 30 / 59 = 0,508, dibulatkan 0,51. Itu matematika yang sama dengan latihannya.
Formatnya punya spesifikasi resmi sejak 17 September 2024: Lottie 1.0 dari Lottie Animation Community, di bawah Linux Foundation. Ada juga dotLottie (.lottie): file ZIP berisi manifest.json, folder a/ untuk animasinya, dan opsional i/ (gambar), t/ (tema), s/ (state machine). Biasanya lebih kecil dari JSON polosnya.
Memutar Lottie di web
Pemutar klasiknya lottie-web dari Airbnb (MIT, versi 5.13.0, rilis terakhir 21 Mei 2025):
import lottie from 'lottie-web/build/player/lottie_svg';
const anim = lottie.loadAnimation({
container: document.querySelector('.cek'), // elemen tempat SVG-nya dibuat
renderer: 'svg', // 'svg' atau 'canvas'
loop: false,
autoplay: false,
animationData: cekJson, // atau path: '/animasi/cek.json'
});
anim.play(); // putar
anim.pause(); // jeda di frame sekarang
anim.stop(); // berhenti dan kembali ke frame 0
anim.setSpeed(2); // dua kali lebih cepat: 2 detik jadi 1 detik
anim.goToAndStop(30, true); // lompat ke frame 30 (true = angka frame, bukan milidetik)
anim.playSegments([0, 15], true); // putar frame 0 sampai 15 saja
setSpeed(2) lalu play() membuat animasinya dua kali lebih cepat, bukan diputar dua kali. anim.totalFrames berisi 60, dan event complete memberi tahu saat selesai.
Pemutar yang lebih baru, @lottiefiles/dotlottie-web (MIT, versi 0.81.0), menggambar dengan mesin WebAssembly ke <canvas>, membaca JSON maupun .lottie, dan punya DotLottieWorker yang menggambar di Web Worker, di luar main thread.
Biayanya: ukuran dan CPU
Kami ukur dari paketnya dan dengan memutar check-mark yang sama selama 2 detik di Chromium 147:
| Yang diunduh (gzip) | JavaScript di main thread, 2 detik | Layout | |
|---|---|---|---|
| SVG + CSS | 312 byte (515 byte sebelum gzip), tanpa JavaScript | 0 ms | 0 |
lottie-web lottie_svg.min.js |
62 KB pemutar (243 KB sebelum gzip) + 1,6 KB JSON | 16,4 ms, 237 kali rAF; 43,1 ms dengan CPU 4x lebih lambat | 60 |
| dotlottie-web | 33 KB JavaScript + 496 KB WebAssembly | 53,4 ms | gak ada, canvas |
dotlottie-web DotLottieWorker |
sama | hampir 0; 51,6 ms pindah ke worker | gak ada |
Itu jawaban tebakannya: versi Lottie mengunduh sekitar 64 KB (pemutarnya sendiri 62 KB), versi SVG + CSS 312 byte. Untuk satu ikon, hampir semua biayanya adalah pemutar. Versi lengkap lottie.min.js lebih besar lagi: 306 KB, 76 KB gzip. Pemutar dotlottie-web juga mengambil file WebAssembly-nya dari CDN jsDelivr secara bawaan.
Lottie layak dipakai untuk ilustrasi rumit yang dibuat desainer di After Effects, apalagi kalau dipakai di banyak tempat dan juga di aplikasi Android dan iOS. Untuk check-mark, CSS sudah cukup.
Check-mark yang sama dengan SVG + CSS
<svg class="cek" width="24" height="24" viewBox="0 0 48 48" aria-hidden="true">
<path pathLength="1" d="M24 4a20 20 0 1 1 0 40a20 20 0 1 1 0-40" /> <!-- cincin -->
<path pathLength="1" d="M15 24.5l6.5 6.5L33 18" /> <!-- centang -->
</svg>
.cek path {
fill: none; stroke: #4ade80; stroke-width: 3; stroke-linecap: round;
stroke-dasharray: 1; /* satu garis putus-putus sepanjang path */
stroke-dashoffset: 1; /* digeser sepanjang path: belum terlihat */
animation: gambar 300ms ease-out forwards;
}
.cek path + path { animation-delay: 200ms; }
@keyframes gambar { to { stroke-dashoffset: 0; } } /* digeser kembali ke 0: tergambar */
@media (prefers-reduced-motion: reduce) {
.cek path { animation: none; stroke-dashoffset: 0; }
}
- Efek "menggambar" (draw-on) =
stroke-dasharraysepanjang path, lalustroke-dashoffsetdianimasikan dari panjang path ke 0. pathLength="1"membuat panjang path dianggap 1, jadi kamu gak perlu mengukurnya. Tanpa itu, ukur denganpath.getTotalLength()di JavaScript dan pakai angkanya.stroke-dashoffsetbukan properti compositor: dia di-paint ulang tiap frame. Saat main thread kami blokir 500 ms, versi CSS ini juga berhenti (0 frame), sama seperti lottie-web (1 frame). Murah, tapi bukan kebal.
SVG juga punya animasi bawaannya sendiri, SMIL (<animate>). Rencana Chrome untuk menghapusnya di 2015 sudah dibatalkan; SMIL jalan di ketiga mesin browser.
Aksesibilitas
- Animasi hiasan diberi
aria-hidden="true". Pesannya sudah ada di teks toast denganrole="status", yang dibacakan pembaca layar. Ikon yang ikut dibacakan cuma menambah suara. - "Kurangi gerakan" = langsung frame terakhir. Di CSS,
animation: nonedengan keadaan akhirnya. Di lottie-web:if (reduce) anim.goToAndStop(anim.totalFrames - 1, true); else anim.play();. - Jangan berulang terus. Ikon sukses cukup sekali (
loop: false). Gerakan yang jalan sendiri lebih dari 5 detik butuh tombol jeda (WCAG 2.2.2).
⚠️ Jebakan yang sering ketemu
- Pemutar 62 KB untuk satu ikon. Ukur dulu; ikon sederhana lebih ringan dengan SVG + CSS.
- Progress dibagi
durationFrames. Frame terakhir adalahdurationFrames - 1, jadi frame 30 dari 60 = 30 / 59 = 0,51, bukan 0,5. - Frame ditahan ke
durationFrames. Frame 60 gak ada; tahan kedurationFrames - 1di atas dan0di bawah. - Lupa
aria-hiddendan "Kurangi gerakan". Pasang keduanya di setiap animasi hiasan.
TL;DR: Lottie = animasi sebagai JSON (diekspor dari After Effects lewat plugin Bodymovin; spesifikasi Lottie 1.0 sejak 17 September 2024) yang digambar ulang setiap frame oleh pemutar JavaScript. fr frame per detik, ip/op frame awal dan akhir, layers berisi bentuk (sh), stroke (st), dan trim path (tm); durasi = frame / fps × 1000 (60 / 30 = 2.000 ms), frame terakhir = jumlah frame - 1, progress = frame / (jumlah frame - 1) (frame 30 = 0,51). dotLottie (.lottie) = ZIP berisi manifest.json dan a/. lottie-web 5.13.0: loadAnimation, play, pause, stop, setSpeed(2) (dua kali lebih cepat), goToAndStop(30, true). Biayanya: check-mark Lottie mengunduh sekitar 64 KB gzip (pemutar 62 KB) dan menjalankan 16,4 ms JavaScript per 2 detik di main thread; versi SVG + CSS 312 byte dan 0 ms JavaScript. dotlottie-web menggambar dengan WebAssembly ke canvas dan bisa pindah ke worker. Efek menggambar di CSS: stroke-dasharray + stroke-dashoffset dari panjang path ke 0 (pathLength="1"). Animasi hiasan diberi aria-hidden="true", dan "Kurangi gerakan" langsung menampilkan frame terakhir.