Impeller to nowoczesny silnik renderowania dla Flutter, opracowany przez Google w celu zastąpienia Skia i wyeliminowania jej fundamentalnych problemów: zacięć shaderów (jank) przy pierwszym renderowaniu klatek, wysokiego zużycia pamięci i trudności w obsłudze różnych backendów graficznych. W przeciwieństwie do Skia, Impeller kompiluje shadery z wyprzedzeniem (offline), używa SPIR-V jako pośredniej reprezentacji i działa bezpośrednio z Vulkan, Metal i Direct3D 12. Według danych Flutter Team (2025), Impeller eliminuje do 95% zacięć shaderów, zapewniając przewidywalne 60 FPS nawet na urządzeniach podstawowych.
Najważniejsze
Impeller — to graficzny silnik renderowania z otwartym kodem źródłowym, napisany w C++, który jest rozwijany przez zespół Flutter w celu zastąpienia Skia jako głównego renderera. Projekt został ogłoszony w 2021 roku jako odpowiedź na wieloletni problem shader jank, na który cierpi Skia. Impeller nie jest forkiem Skia — to całkowicie nowa implementacja, zaprojektowana z uwzględnieniem ograniczeń mobilnych GPU i nowoczesnych API graficznych.
Główna idea Impeller polega na przeniesieniu kompilacji shaderów na etap budowania aplikacji, a nie podczas jej działania. W Skia shadery są kompilowane przy pierwszym użyciu, gdy użytkownik już wchodzi w interakcję z aplikacją. Impeller kompiluje wszystkie shadery z wyprzedzeniem (offline), pakuje je w binarny format SPIR-V i dostarcza wraz z aplikacją. W czasie działania Impeller ładuje wstępnie skompilowane shadery, co eliminuje opóźnienia związane z kompilacją.
Impeller rozwiązuje również problem zużycia pamięci. Skia tworzy wiele tymczasowych obiektów (tekstur, buforów) w procesie renderowania, co prowadzi do fragmentacji pamięci na urządzeniach z ograniczonymi zasobami. Impeller używa pul pamięci (memory pools) i ponownie wykorzystuje przydzielone zasoby, zmniejszając szczytowe zużycie pamięci o 30–40%.
SPIR-V (Standard Portable Intermediate Representation) — to pośrednia reprezentacja shaderów opracowana przez Khronos Group. Impeller używa SPIR-V jako uniwersalnego formatu dla wszystkich shaderów. Na etapie budowania shadery w języku Impeller (własny C++ DSL do opisywania efektów) są kompilowane do SPIR-V. W czasie działania SPIR-V jest ładowany i translowany na format specyficzny dla platformy — MSL dla Metal, GLSL dla Vulkan lub DXIL dla Direct3D 12.
Architektura Impeller składa się z kilku warstw, z których każda wykonuje ściśle określone zadanie: przetwarzanie listy poleceń renderowania, zarządzanie zasobami GPU i wykonywanie shaderów. Taka modułowość umożliwia łatwe dodawanie obsługi nowych API graficznych.
Dolna warstwa — to abstrakcja nad API graficznym (Vulkan, Metal, Direct3D 12). Impeller nie obsługuje OpenGL, ponieważ OpenGL nie zapewnia możliwości efektywnej kompilacji offline shaderów. Na tym poziomie zaimplementowano: zarządzanie buforami wierzchołków, tworzenie i buforowanie pipeline'ów (potoków graficznych), synchronizację GPU. Pipeline w Impeller — to wstępnie skompilowany stan GPU, który obejmuje shadery, ustawienia rasteryzacji i blendingu. Wszystkie pipeline'y są tworzone na etapie inicjalizacji, co eliminuje kompilację podczas renderowania.
Środkowa warstwa — to system zarządzania zasobami. Alokuje i ponownie wykorzystuje zasoby GPU: tekstury, bufory, samplery. Zamiast tworzenia nowej tekstury przy każdej klatce, Impeller utrzymuje pulę tekstur o różnych rozmiarach i formatach. Pula pamięci automatycznie zwraca nieużywane zasoby i może się rozszerzać w razie potrzeby, ale bez fragmentacji charakterystycznej dla Skia.
Górna warstwa — to graf renderowania, do którego Flutter Engine przekształca polecenia Canvas API. Impeller przyjmuje Display List (listę poleceń rysowania) i buduje z niej graf zależności operacji. Graf jest optymalizowany: usuwane są zbędne przejścia renderowania, łączone są operacje o tym samym stanie GPU. Następnie graf jest kompilowany w sekwencję wywołań Vulkan/Metal z wykorzystaniem wstępnie utworzonych pipeline'ów.
Każda klatka przechodzi przez stały potok: Display List → graf renderowania → kompilacja grafu → wysłanie poleceń GPU. Dodatkowe przejścia mogą być dodawane dla efektów końcowych (rozmycie, cienie) lub przygotowania bufora głębi. Czas klatki w Impeller jest bardziej przewidywalny niż w Skia, ponieważ brak jest niedeterministycznych opóźnień na kompilację shaderów.
Porównanie Impeller i Skia pokazuje różnice w podejściu do renderowania. Skia — to uniwersalna biblioteka 2D ogólnego przeznaczenia, a Impeller — to wyspecjalizowany silnik dla Flutter, zoptymalizowany pod wymagania mobilnego UI.
| Parametr | Skia | Impeller |
|---|---|---|
| Shadery | Kompilacja na bieżąco (runtime) | Kompilacja offline (build time) |
| Shader jank | 50–200 ms na pierwszą klatkę | Brak (0 ms) |
| Format shaderów | Własny (SkSL) | SPIR-V (uniwersalny) |
| Backendy GPU | OpenGL, Vulkan, Metal | Vulkan, Metal, Direct3D 12 |
| Zużycie pamięci | Wysokie (tymczasowe tekstury) | Pule pamięci, do -40% |
| Platformy | Android, iOS, Web, Desktop | Android, iOS, Desktop |
| Status | Stabilny (główny) | Preview (zastępuje Skia) |
Kluczowa różnica — podejście do shaderów. Skia kompiluje shadery w momencie użycia, tworząc shader jank przy pierwszym renderowaniu nieznanych efektów. Impeller eliminuje to dzięki kompilacji offline. Skia obsługuje również OpenGL, co jest niezbędne dla wersji webowej Flutter, ale Impeller rezygnuje z OpenGL na rzecz nowocześniejszych API, co daje lepszą wydajność na urządzeniach mobilnych.
Dla aplikacji Flutter przejście na Impeller nie wymaga zmiany kodu. Impeller implementuje ten sam Canvas API co Skia, więc wszystkie widżety, animacje i niestandardowe rysowania działają tak samo. Wsteczna zgodność jest zapewniona na poziomie Flutter Engine — silnik wybiera renderer (Skia lub Impeller) na etapie inicjalizacji aplikacji.
Impeller zapewnia kilka wymiernych zalet w porównaniu ze Skia, które bezpośrednio wpływają na doświadczenie użytkownika i wydajność aplikacji Flutter.
Shader jank — główny problem Skia, który Impeller rozwiązuje całkowicie. Gdy aplikacja Flutter wyświetla nowy ekran z gradientami, maskami lub niestandardowymi blendami, Skia kompiluje shadery podczas animacji, co prowadzi do pomijania klatek. Impeller kompiluje wszystkie shadery na etapie budowania, więc pierwsza klatka renderuje się tak samo szybko jak kolejne. Na urządzeniach z wolnym GPU (MediaTek Helio, Qualcomm 400 series) różnica jest szczególnie widoczna — do 200 ms opóźnienia na każdy nowy typ efektu w Skia wobec 0 ms w Impeller.
Impeller używa pul zasobów do zarządzania pamięcią GPU. W Skia każda klatka może tworzyć nowe tekstury dla tymczasowych powierzchni, szczególnie przy renderowaniu z przezroczystością lub użyciu saveLayer. Impeller ponownie wykorzystuje tekstury między klatkami, co zmniejsza szczytowe zużycie pamięci o 30–40% na Androidzie i do 25% na iOS. Jest to szczególnie ważne dla aplikacji z długimi listami i animacjami, w których Skia mogła powodować błędy OOM na urządzeniach z 2 GB RAM.
W Skia czas renderowania klatki może się różnić w zależności od tego, które shadery są już skompilowane. Pierwsza klatka z nowym efektem może zajmować 50–200 ms, podczas gdy kolejne — 3–5 ms. Ta nieprzewidywalność utrudnia optymalizację i testowanie. Impeller zapewnia równomierny czas klatki, ponieważ wszystkie shadery są już skompilowane, a alokacja pamięci jest przewidywalna. Flutter Engine z Impeller może dokładniej obliczać budżet czasu na każdą klatkę.
Impeller działa bezpośrednio z Vulkan (Android), Metal (iOS) i Direct3D 12 (Windows), bez warstwy OpenGL. Daje to kilka zalet: mniejsze opóźnienie sterownika (nawet o 50% mniejsze niż przez OpenGL), bezpośrednią kontrolę nad pamięcią GPU i dostęp do nowoczesnych możliwości (architektura kafelkowa GPU, GPU-driven rendering). OpenGL nie jest już rozwijany, a jego sterowniki na urządzeniach mobilnych często stają się wąskim gardłem wydajności.
Impeller znajduje się w aktywnej fazie rozwoju i jest dostępny w kanałach Flutter Master i Beta. Od Flutter 3.16 Impeller jest domyślnie włączony na iOS, a na Androidzie — opcjonalnie przez flagę konfiguracji. Całkowite zastąpienie Skia przez Impeller oczekiwane jest w jednej ze stabilnych wersji Flutter w 2026 roku.
Na iOS Impeller działa przez Metal i jest domyślnie włączony od Flutter 3.16. Zespół Flutter zaleca testowanie aplikacji na Impeller i zgłaszanie problemów. Do wycofania na Skia używa się flagi Impeller w pliku Info.plist: FlutterEnableImpeller = NO. Według danych Flutter Team, 92% aplikacji na iOS działa na Impeller bez widocznych regresji, a wydajność animacji poprawia się o 25–40%.
Na Androidzie Impeller działa przez Vulkan. Aby włączyć, w AndroidManifest.xml dodaje się meta-tag: io.flutter.embedded_views_preview. Zespół Flutter kontynuuje optymalizację Impeller pod różne architektury GPU (Adreno, Mali, PowerVR). Głównym wyzwaniem na Androidzie jest obsługa urządzeń bez Vulkan (Android < 7.0 lub stare GPU). Dla takich urządzeń będzie używany zapasowy backend na Skia lub Impeller z programową rasteryzacją.
Na Windows Impeller działa przez Direct3D 12 (włączony w Flutter Master). Na macOS i Linux — przez Metal i Vulkan odpowiednio. Dla Web Impeller nie jest planowany, ponieważ wersja webowa Flutter używa CanvasKit (Skia przez WebAssembly), a shader jank nie jest dla niej krytycznym problemem ze względu na inny mechanizm kompilacji shaderów w przeglądarce. Wersja webowa będzie nadal używać Skia.
Google opublikowało mapę drogową Impeller: 2024 — Impeller domyślnie na iOS; 2025 — Impeller domyślnie na Androidzie i Windows; 2026 — całkowite usunięcie Skia z Flutter Engine. Po tym Flutter będzie używać Impeller jako jedynego silnika renderowania, co uprości wsparcie, zmniejszy rozmiar silnika i poprawi wydajność na wszystkich platformach.
Często zadawane pytania
Na iOS Impeller jest domyślnie włączony od Flutter 3.16. Na Androidzie dodaj w AndroidManifest.xml meta-tag io.flutter.embedded_views_preview z wartością true. Na Windows użyj flagi --enable-impeller przy uruchamianiu. We wszystkich przypadkach można wymusić włączenie przez FlutterEngine w kodzie Dart.
Skia działa, ale ma fundamentalne problemy: shader jank (50–200 ms opóźnienia na kompilację shaderów), wysokie zużycie pamięci i ograniczenia architektury OpenGL. Impeller jest zaprojektowany specjalnie dla Flutter i eliminuje te problemy dzięki kompilacji offline shaderów i pulom pamięci.
Tak, Impeller implementuje ten sam Canvas API co Skia. Wszystkie standardowe widżety Flutter — tekst, obrazy, animacje, niestandardowe paint — działają na Impeller bez zmian. Wsteczna zgodność jest zapewniona na poziomie Flutter Engine, a przejście jest przezroczyste dla programisty.
Nie, aplikacja używa jednego silnika renderowania na raz. Wybór jest dokonywany przy inicjalizacji Flutter Engine przez flagę. Przełączanie między Skia a Impeller podczas działania aplikacji jest niemożliwe — renderer jest ustalany przed utworzeniem pierwszej instancji FlutterEngine.
Skia będzie nadal istnieć jako samodzielna biblioteka Google dla Chrome, Androida i innych projektów. We Flutter Skia zostanie zastąpiona przez Impeller jako główny renderer. Skia pozostanie dla wersji webowej Flutter (przez CanvasKit) i jako opcja zapasowa dla urządzeń bez obsługi Vulkan/Metal.
Podsumowanie
Opracujemy aplikację mobilną pod klucz
IT Sectr tworzy aplikacje na iOS i Androida dla startupów i firm od 2017 roku. Doradzimy Ci i zaproponujemy najlepsze rozwiązanie.
Przeczytaj również