# Framer Motion vs Animasi CSS: Kapan Menggunakan Masing-masing

> Perbandingan praktis Framer Motion dan animasi CSS murni — ukuran bundle, performa, DX, dan pengalaman nyata saya menggunakan keduanya di matthewswong.com.

URL: https://www.matthewswong.com/id/blog/framer-motion-vs-css-animations/

- Author: Matthews Wong (https://www.matthewswong.com/id/about/)
- Published: 2025-06-10
- Updated: 2025-06-10
- Category: Web Dev

Framer Motion (sekarang diganti nama menjadi Motion) berbobot sekitar 34KB yang dimampatkan — 32KB jika Anda menggunakan impor penuh. Animasi CSS murni berjalan di thread compositor dan menambahkan 0KB ke bundle JavaScript Anda. Portofolio saya (matthewswong.com) menggunakan Framer Motion untuk transisi halaman dan animasi komponen. Saya juga membangun proyek di mana mengganti Framer Motion dengan CSS menghemat 50KB bundle dan meningkatkan skor Lighthouse sebesar 8 poin.

## Performa: Angka Nyata

Transform dan transisi CSS berjalan di thread compositor GPU — sepenuhnya terpisah dari thread JavaScript utama. Tidak ada eksekusi JavaScript berarti animasi tidak bersaing dengan event handler, render, atau kode lain untuk waktu CPU. Animasi JavaScript (termasuk Framer Motion) berjalan di thread utama via requestAnimationFrame. Framer Motion menggunakan akselerasi GPU secara cerdas, tapi orkestrasi JavaScript tetap terjadi di thread utama.

### Ukuran Bundle dan Lazy Loading

Bundle 34KB Framer Motion penting untuk performa, terutama di mobile. Kabar baiknya: komponen LazyMotion Motion mengurangi bundle awal menjadi ~6KB dengan memuat fitur sesuai permintaan. Gunakan LazyMotion dengan domAnimation untuk fitur yang paling umum (animate, initial, exit, transition) — ini mencakup 90% kasus penggunaan dengan 6KB alih-alih 34KB.

> Dari mengoptimalkan skor Lighthouse matthewswong.com setelah menambahkan Framer Motion: bungkus semua komponen motion dalam LazyMotion dengan domAnimation dan domMax hanya di mana diperlukan. Juga, tambahkan will-change: transform ke elemen yang sering dianimasikan — ini memberi petunjuk ke browser untuk mempromosikannya ke lapisan compositor mereka sendiri sebelum animasi dimulai. Kombinasi ini menurunkan skor layout shift terkait animasi saya dari 0,12 menjadi 0,02.

## Kapan Animasi CSS Menang

CSS menang untuk: (1) Animasi sederhana dan stateless — efek hover, spinner loading, shimmer skeleton, umpan balik penekanan tombol. Ini selalu harus CSS. (2) Situs portofolio dan halaman marketing di mana 34KB JavaScript library animasi mengurangi poin Lighthouse nyata. (3) Animasi yang tidak bergantung pada state JavaScript — jika animasi berjalan dengan cara yang sama terlepas dari state aplikasi, CSS keyframe adalah alat yang tepat.

### Kapan Framer Motion Menang

Framer Motion menang untuk: (1) Animasi layout — menganimasikan antar state layout (pengurutan daftar, kartu yang berkembang) dengan prop layout. (2) Animasi keluar — menganimasikan komponen saat unmount. AnimatePresence menangani ini dengan elegan. (3) Gerakan berbasis fisika — animasi spring, drag dengan momentum, chaining gesture. (4) Transisi elemen bersama antar halaman — layoutId Framer Motion menangani ini; CSS saja tidak bisa.

> **Framer Motion dan React Server Components Tidak Cocok**

> Komponen Framer Motion adalah Client Components — mereka membutuhkan browser DOM dan React client runtime. Setiap komponen yang dibungkus dalam '<'motion.div> memerlukan 'use client'. Dalam aplikasi Next.js App Router, membungkus bagian besar halaman Anda dalam komponen motion memaksa bagian-bagian tersebut menjadi Client Components, kehilangan manfaat Server Component. Jaga Framer Motion di level daun — bungkus elemen interaktif individual, bukan bagian halaman yang seluruhnya.

## Pendekatan Hibrida

Pendekatan saya saat ini di matthewswong.com: CSS Tailwind animate-* untuk animasi mikro (hover, focus, loading state), Framer Motion dengan LazyMotion untuk animasi makro (transisi halaman, penampilan konten, gesture interaktif). Halaman masuk dengan fade-in Framer Motion, tapi setiap state hover tombol adalah Tailwind CSS transition-colors. Ini menjaga bundle tetap fokus — Framer Motion mendapatkan 6KB-nya dengan fitur yang tidak bisa ditandingi CSS.

## Yang Saya Gunakan dan Mengapa

Untuk proyek apa pun dengan animasi interaktif (drag, spring, transisi layout, animasi keluar), saya menggunakan Framer Motion dengan LazyMotion. DX sangat baik — state animasi deklaratif, animasi layout bersama, dan dukungan gesture yang membutuhkan berminggu-minggu untuk diimplementasikan dengan benar dalam vanilla JS. Untuk proyek yang lebih sederhana atau halaman yang kritis terhadap performa, saya menggunakan CSS saja.

## Mengukur Performa Animasi

Ukur sebelum mengoptimalkan. Panel Performa Chrome DevTools menampilkan frame rate animasi dan hambatan thread utama. Panel Rendering menampilkan paint flashing (merah berarti repainting) dan lapisan kompositing. Animasi CSS yang hanya menganimasikan properti transform dan opacity akan ditampilkan sebagai compositor-thread saja. Untuk Framer Motion, verifikasi bahwa elemen yang Anda animasikan adalah GPU-composited.

## Sumber & Bacaan Lanjut

- Motion.dev — Web Animation Performance Tier List — https://motion.dev/magazine/web-animation-performance-tier-list
- LogRocket — Comparing the Best React Animation Libraries for 2026 — https://blog.logrocket.com/best-react-animation-libraries/
- Medium — Why Framer Motion Still Beats CSS Animations in 2025 — https://theekshanachamodhya.medium.com/why-framer-motion-still-beats-css-animations-in-2025-16b3d74eccbd

| Dimensi | Framer Motion | CSS Animations |
| --- | --- | --- |
| Ukuran bundle | Sekitar 34KB minified dan gzipped | 0KB tambahan ke bundle JavaScript |
| Thread eksekusi | Berjalan di main thread lewat JavaScript | Berjalan di compositor thread untuk transform dan opacity |
| Dukungan gesture | Drag, hover, dan tap gesture bawaan | Butuh event handling JavaScript manual |
| Animasi layout | Transisi layout otomatis berbasis FLIP | Butuh keyframes manual untuk perubahan layout |
| Orkestrasi | Variants deklaratif dan staggered children | Chaining animation-delay manual |
| Batas performa | Bisa drop frame di perangkat low-end saat pemakaian berat | Konsisten mencapai 60fps untuk transform dan opacity |
| Paling cocok untuk | UI kompleks, interaktif, berbasis gesture | Transisi sederhana dan animasi halaman statis |

## Source links

- https://motion.dev/magazine/web-animation-performance-tier-list
- https://blog.logrocket.com/best-react-animation-libraries/
- https://theekshanachamodhya.medium.com/why-framer-motion-still-beats-css-animations-in-2025-16b3d74eccbd

## FAQ

### Kapan sebaiknya memilih Framer Motion daripada animasi CSS murni?

Framer Motion unggul untuk kasus yang tidak bisa ditangani CSS dengan bersih: animasi layout (pengurutan daftar, kartu yang berkembang via prop layout), animasi keluar saat komponen unmount via AnimatePresence, gerakan berbasis fisika seperti spring dan drag dengan momentum, serta transisi elemen bersama antar halaman menggunakan layoutId. Jika animasi bergantung pada state JavaScript atau membutuhkan chaining gesture, Framer Motion adalah pilihan yang tepat.

### Seberapa besar Framer Motion menambah bundle JavaScript, dan bisakah dikurangi?

Bundle penuh Framer Motion (sekarang bernama Motion) berukuran sekitar 34KB setelah dimampatkan. Anda bisa mengurangi muatan awal menjadi sekitar 6KB dengan menggunakan komponen LazyMotion bersama domAnimation, yang mencakup fitur paling umum — animate, initial, exit, dan transition — untuk sekitar 90% kasus penggunaan. domMax hanya perlu ditambahkan di tempat yang benar-benar diperlukan.

### Mengapa animasi CSS lebih unggul dari animasi JavaScript di thread utama?

Transform dan transisi CSS berjalan di thread compositor GPU, sepenuhnya terpisah dari eksekusi JavaScript. Artinya animasi tidak bersaing dengan event handler, proses render, atau kode lain untuk waktu CPU. Framer Motion tetap menggunakan requestAnimationFrame di thread utama untuk orkestrasinya, meski menerapkan akselerasi GPU via transform: translate3d() dan will-change. Untuk animasi masuk sederhana seperti fade-in atau slide-up, CSS jelas lebih cepat.

### Seberapa besar peningkatan performa yang didapat dari pendekatan hibrida di matthewswong.com?

Mengganti sebagian penggunaan Framer Motion dengan CSS menghemat 50KB bundle dan meningkatkan skor Lighthouse sebesar 8 poin di halaman yang kritis terhadap performa. Dari sisi animasi, membungkus komponen motion dalam LazyMotion dengan domAnimation dan menambahkan will-change: transform ke elemen yang sering dianimasikan berhasil menurunkan skor layout shift terkait animasi dari 0,12 menjadi 0,02.

### Bagaimana cara menyusun Framer Motion yang benar dalam proyek Next.js App Router?

Komponen Framer Motion adalah Client Components dan memerlukan direktif 'use client'. Membungkus bagian besar halaman dalam komponen motion memaksa bagian tersebut keluar dari server, sehingga kehilangan manfaat Server Component. Jaga Framer Motion di level daun — bungkus elemen interaktif individual, bukan keseluruhan layout halaman — agar pengambilan data dan struktur halaman tetap berjalan di sisi server.

---

- HTML version: https://www.matthewswong.com/id/blog/framer-motion-vs-css-animations/
- English: https://www.matthewswong.com/en/blog/framer-motion-vs-css-animations/
- Site index for agents: https://www.matthewswong.com/llms.txt
- Sitemap: https://www.matthewswong.com/sitemap.xml
- API description (OpenAPI): https://www.matthewswong.com/openapi.json
