Skia & Impeller #
Dua nama ini adalah inti dari bagaimana Flutter mengubah instruksi gambar menjadi piksel di layar. Skia adalah engine yang membesarkan Flutter sejak awal. Impeller adalah penerusnya — dibangun khusus untuk Flutter dan dirancang menyelesaikan masalah fundamental yang tidak bisa dipecahkan Skia. Memahami keduanya berarti memahami mengapa Flutter bisa (dan terkadang tidak bisa) memberikan animasi yang benar-benar smooth.
Konteks: Apa Itu Rendering Engine? #
Sebelum membandingkan keduanya, penting untuk memahami peran rendering engine dalam pipeline Flutter. Rendering engine menerima layer tree dari Framework dan mengeksekusinya menjadi piksel di frame buffer GPU:
Layer Tree (dari Framework)
|
v
Rendering Engine <-- Skia atau Impeller
(Raster Thread)
|
v
GPU Draw Calls
|
v
Frame Buffer (piksel)
|
v
Layar
Rendering engine adalah komponen yang paling menentukan seberapa smooth animasi terasa di tangan pengguna.
Skia — Fondasi Awal Flutter #
Skia adalah library grafis 2D open-source yang dikembangkan oleh Google. Ia bukan dibuat khusus untuk Flutter — Skia digunakan di banyak produk Google termasuk Chrome, Android, dan YouTube. Flutter mengadopsinya sejak awal karena sudah matang dan terbukti.
Arsitektur Skia: Immediate Mode Rendering #
Skia menggunakan pendekatan Immediate Mode Rendering (IMR) — setiap drawing command dieksekusi langsung ke GPU saat perintah tersebut diterima:
Frame N dimulai:
"Gambar rect biru" --> langsung eksekusi ke GPU
"Gambar teks 'Halo'" --> langsung eksekusi ke GPU
"Gambar lingkaran merah"--> langsung eksekusi ke GPU
Frame N selesai
Frame N+1 dimulai:
"Gambar rect biru" --> eksekusi ULANG dari awal
"Gambar teks 'Halo'" --> eksekusi ULANG dari awal
"Gambar lingkaran merah"--> eksekusi ULANG dari awal
Frame N+1 selesai
Setiap frame digambar penuh dari awal — tidak peduli apakah ada sesuatu yang berubah atau tidak.
Bagaimana Skia Menangani Shader #
Shader adalah program kecil yang berjalan di GPU — menentukan warna, gradien, blur, shadow, dan efek visual lainnya. Di Skia, shader dikompilasi menggunakan pendekatan JIT (Just-In-Time):
Pengguna membuka screen baru dengan animasi gradient:
Frame 1:
"Butuh shader gradient..."
Shader belum ada --> COMPILE sekarang (~50-300ms)
--> JANK! Frame ini butuh jauh lebih dari 16ms
--> Animasi terlihat patah di frame pertama
Frame 2:
Shader sudah di-cache GPU --> eksekusi normal (~5ms)
--> Smooth
Frame 3, 4, 5, ...:
Cache masih ada --> eksekusi normal
--> Smooth
Inilah yang disebut shader compilation jank — jeda yang hanya terjadi saat shader pertama kali dibutuhkan. Masalahnya: jank ini selalu terjadi di momen yang paling terlihat pengguna, yaitu saat pertama kali membuka screen baru atau menjalankan animasi yang belum pernah berjalan sebelumnya.
Kelebihan Skia #
- Matang dan battle-tested — digunakan selama belasan tahun di Chrome, Android, YouTube
- Dukungan platform sangat luas — OpenGL, Vulkan, Metal, Direct3D, software rendering
- Ekosistem besar — banyak optimasi dan fix yang terakumulasi selama bertahun-tahun
- Web support — CanvasKit (Skia compiled to WebAssembly) masih menjadi backbone Flutter Web
Kelemahan Skia #
- Shader compilation jank — masalah fundamental yang tidak bisa diselesaikan tanpa redesign
- Immediate mode — selalu menggambar ulang seluruh frame meskipun hanya 1 piksel yang berubah
- Ketergantungan pada OpenGL — OpenGL sedang dideprecate oleh Apple; Skia harus bridging ke Metal
- Binary size lebih besar — menyertakan infrastruktur shader compilation runtime (~17% ukuran engine)
Mengapa Impeller Diciptakan #
Shader compilation jank bukan bug yang bisa di-patch — ini adalah konsekuensi arsitektur dari pendekatan JIT shader Skia. Tim Flutter menyimpulkan bahwa satu-satunya cara menyelesaikannya secara permanen adalah membangun rendering engine baru dari awal, dengan prinsip desain yang berbeda fundamental.
Impeller mulai dikembangkan secara serius sejak 2021 dengan satu tujuan utama: menghilangkan shader compilation jank sepenuhnya, bukan meminimalkannya.
Impeller — Rendering Engine Generasi Baru #
Impeller adalah rendering engine yang dibangun khusus untuk Flutter — tidak digunakan oleh produk Google lain. Ini berarti Impeller bisa dioptimalkan sepenuhnya untuk kebutuhan spesifik Flutter tanpa harus berkompromi dengan use case lain.
Arsitektur Impeller: Tile-Based Retained Rendering #
Impeller menggunakan dua pendekatan berbeda dari Skia sekaligus:
Retained Mode Rendering:
Frame N dimulai:
Impeller membandingkan dengan frame sebelumnya
Hanya elemen yang BERUBAH yang digambar ulang
Elemen yang SAMA di-reuse dari GPU buffer cache
Frame N selesai
Frame N+1 dimulai:
Hanya perubahan incremental yang diproses
--> Jauh lebih efisien dari IMR
Frame N+1 selesai
Tile-Based Rendering:
Frame dibagi menjadi tile (misal 256x256 piksel):
+--------+--------+--------+
| Tile 1 | Tile 2 | Tile 3 |
+--------+--------+--------+
| Tile 4 | Tile 5 | Tile 6 |
+--------+--------+--------+
| Tile 7 | Tile 8 | Tile 9 |
+--------+--------+--------+
Jika animasi hanya terjadi di Tile 5:
--> Hanya Tile 5 yang di-rasterisasi ulang
--> Tile lain di-reuse dari cache GPU
--> Efisiensi GPU meningkat drastis
Tile-based rendering sangat cocok untuk tiling GPU yang digunakan di hampir semua perangkat mobile modern (ARM Mali, Apple GPU, Qualcomm Adreno).
AOT Shader Compilation — Solusi Jank #
Inilah perbedaan paling signifikan Impeller dari Skia:
SKIA (JIT Shader):
flutter build ios
|
v
App dikemas --> Shader BELUM dikompilasi
|
v
User buka app --> Jalankan frame pertama
|
v
Shader dibutuhkan --> Compile SEKARANG --> JANK
------------------------------------------------------
IMPELLER (AOT Shader):
flutter build ios
|
v
impellerc mengkompilasi SEMUA shader
(selama proses build, bukan saat runtime)
|
v
App dikemas --> Shader SUDAH dikompilasi
|
v
User buka app --> Shader langsung tersedia
|
v
Tidak ada kompilasi saat runtime --> TIDAK ADA JANK
Impeller menggunakan tool bernama impellerc — Impeller Shader Compiler — yang berjalan saat flutter build. Ia mengkompilasi shader GLSL menjadi format spesifik platform:
GLSL Shader Source
|
v
impellerc (saat build time)
|
+-- Metal Shader Library (.metallib) --> untuk iOS/macOS
+-- SPIR-V Binary --> untuk Vulkan (Android)
+-- OpenGL ES Shader (compiled) --> untuk fallback
Backend GPU Modern: Metal dan Vulkan #
Impeller dirancang sejak awal untuk modern graphics API — bukan OpenGL yang sudah aging:
SKIA:
Utamanya OpenGL --> bridging ke Metal/Vulkan
(Apple mendeprecate OpenGL di iOS sejak 2018)
IMPELLER:
iOS/macOS --> Metal (langsung, native)
Android --> Vulkan (langsung, native)
Fallback --> OpenGL ES (untuk device lama)
Modern API seperti Metal dan Vulkan memberikan:
- Kontrol GPU yang lebih langsung dan granular
- Overhead driver yang lebih rendah
- Paralelisme yang lebih baik (multi-thread GPU command submission)
- Prediktabilitas performa yang lebih tinggi
Concurrency — Multi-Thread Frame Rendering #
Impeller dapat mendistribusikan pekerjaan satu frame ke beberapa CPU thread:
Single frame rendering dengan Impeller:
Thread 1: Proses layer tree atas
Thread 2: Proses layer tree bawah --> paralel
Thread 3: Encode GPU commands
|
v
GPU eksekusi semua sekaligus
Ini sangat efektif di perangkat dengan banyak core CPU seperti iPhone dan Android flagship modern.
Data Performa Nyata #
Beberapa angka yang dilaporkan dari aplikasi produksi dan pengujian resmi:
| Skenario | Skia | Impeller |
|---|---|---|
| Complex clipping frame time | ~450ms | ~11ms |
| Shader compilation jank | Ada (first frame) | Tidak ada |
| Dropped frames (animasi hero) | Baseline | Berkurang >70% |
| Memory usage (kondisi tertentu) | Baseline | ~100MB lebih rendah |
| Power usage (animasi berat) | Baseline | Jauh lebih efisien |
Status Saat Ini (2025) #
Platform Engine Default Catatan
------- ------------- -------
iOS Impeller Default sejak Flutter 3.10
Tidak bisa kembali ke Skia (3.29+)
Android API 29+ Impeller Default sejak Flutter 3.27
Backend: Vulkan
Android < API 29 Impeller Fallback otomatis ke OpenGL ES
(tidak perlu konfigurasi manual)
macOS Impeller Tersedia, behind flag
Web Skia (CanvasKit) Impeller/Wasm dalam pengembangan
Windows/Linux Skia Impeller masih dalam eksplorasi
Cara Menonaktifkan Impeller (untuk Debugging) #
# Nonaktifkan Impeller saat debugging (jika ada rendering bug)
flutter run --no-enable-impeller
# iOS: tidak bisa dinonaktifkan sejak Flutter 3.29
Yang Tetap Menggunakan Skia/Komponen Skia #
Meski Impeller mengambil alih rendering utama, beberapa komponen masih menggunakan Skia:
Impeller menggantikan Skia untuk:
[X] 2D rendering (rect, circle, path, dll.)
[X] Shader execution (gradient, blur, shadow)
[X] Compositing dan layer management
[X] GPU resource management
Masih menggunakan komponen Skia:
[ ] SkParagraph --> text shaping dan layout
[ ] Skia codecs --> image decoding (JPEG, PNG, WebP)
Flutter Web masih sepenuhnya menggunakan:
[ ] CanvasKit (Skia compiled to WebAssembly)
Mengapa text shaping masih pakai SkParagraph?
Text shaping adalah proses yang sangat kompleks — melibatkan ligatur, kerning, BiDi (bidirectional text), dan aturan tipografi yang berbeda-beda per bahasa. SkParagraph sudah sangat matang dan akurat untuk ini. Membangun ulang text shaping dari nol di Impeller akan membutuhkan waktu bertahun-tahun dan berisiko memperkenalkan regresi yang sulit ditemukan. Tim Flutter memutuskan untuk tetap menggunakan SkParagraph sampai ada alternatif yang sama matangnya.
Impeller dan Masa Depan: Flutter GPU #
Impeller membuka pintu untuk sesuatu yang tidak bisa dilakukan Skia: rendering 3D dari Dart.
// Flutter GPU API (eksperimental, 2025)
// Memungkinkan developer menulis shader kustom dan rendering 3D
// langsung dari kode Dart
import 'dart:ui' as ui;
// Render 3D mesh dengan custom shader
void render3DScene(gpu.RenderPass renderPass) {
renderPass
..bindPipeline(myMeshPipeline)
..bindVertexBuffer(meshVertices)
..bindUniform('mvpMatrix', modelViewProjection)
..draw(vertexCount: mesh.vertexCount);
}
Di atas Flutter GPU, tim Flutter sedang membangun Flutter Scene — library untuk mengimpor dan merender model 3D dalam format glTF. Ini akan membuka kemungkinan game, visualisasi data 3D, dan augmented reality yang sebelumnya tidak mungkin dilakukan di Flutter.
Ringkasan #
- Skia adalah rendering engine 2D yang matang dan battle-tested — digunakan Flutter sejak awal tapi punya masalah fundamental: shader compilation jank.
- Shader compilation jank terjadi karena Skia mengkompilasi shader JIT saat runtime — menghasilkan jeda di frame pertama setiap animasi baru.
- Impeller adalah rendering engine baru khusus Flutter — menggunakan tile-based retained rendering dan AOT shader compilation untuk menghilangkan jank sepenuhnya.
- Impeller menarget Metal (iOS/macOS) dan Vulkan (Android) secara langsung — bukan melalui bridging OpenGL seperti Skia.
- Impeller adalah default di iOS (sejak Flutter 3.10, wajib sejak 3.29) dan Android API 29+ (sejak Flutter 3.27).
- Text shaping dan image decoding masih menggunakan komponen Skia (SkParagraph, Skia codecs) — Impeller hanya menggantikan rendering grafis.
- Flutter GPU API yang dibangun di atas Impeller membuka kemungkinan rendering 3D dan shader kustom langsung dari Dart — sesuatu yang tidak pernah bisa dilakukan Skia.
← Sebelumnya: Rendering Pipeline Berikutnya: Perbandingan Native →