Impeller è un moderno motore di rendering per Flutter, sviluppato da Google per sostituire Skia e risolverne i problemi fondamentali: i shader jank durante il primo rendering dei fotogrammi, l'elevato consumo di memoria e la complessità di supportare diversi backend grafici. A differenza di Skia, Impeller compila gli shader in anticipo (offline), utilizza SPIR-V come rappresentazione intermedia e funziona direttamente con Vulkan, Metal e Direct3D 12. Secondo Flutter Team (2025), Impeller elimina fino al 95% degli shader jank, garantendo 60 FPS prevedibili anche su dispositivi di fascia bassa.
Punti chiave
Impeller è un motore di rendering grafico open source scritto in C++, sviluppato dal team Flutter per sostituire Skia come renderer principale. Il progetto è stato annunciato nel 2021 come risposta al problema di lunga data dello shader jank di cui soffre Skia. Impeller non è un fork di Skia — è un'implementazione completamente nuova progettata tenendo conto dei limiti delle GPU mobili e delle API grafiche moderne.
L'idea principale di Impeller è spostare la compilazione degli shader alla fase di build dell'applicazione, anziché al runtime. In Skia, gli shader vengono compilati al primo utilizzo, quando l'utente sta già interagendo con l'applicazione. Impeller compila tutti gli shader in anticipo (offline), li impacchetta nel formato binario SPIR-V e li distribuisce con l'applicazione. Durante l'esecuzione, Impeller carica gli shader precompilati, eliminando i ritardi di compilazione.
Impeller risolve anche il problema del consumo di memoria. Skia crea molti oggetti temporanei (texture, buffer) durante il rendering, causando frammentazione della memoria sui dispositivi con risorse limitate. Impeller utilizza pool di memoria e riutilizza le risorse allocate, riducendo il consumo di picco di memoria del 30–40%.
SPIR-V (Standard Portable Intermediate Representation) è una rappresentazione intermedia degli shader sviluppata dal Khronos Group. Impeller utilizza SPIR-V come formato universale per tutti gli shader. Durante la fase di build, gli shader scritti nel linguaggio Impeller (un DSL C++ personalizzato per descrivere effetti) vengono compilati in SPIR-V. In fase di esecuzione, SPIR-V viene caricato e tradotto in un formato specifico della piattaforma — MSL per Metal, GLSL per Vulkan o DXIL per Direct3D 12.
L'architettura di Impeller è composta da diversi livelli, ciascuno dei quali esegue un compito strettamente definito: elaborazione dell'elenco dei comandi di rendering, gestione delle risorse GPU ed esecuzione degli shader. Questa modularità rende facile aggiungere il supporto per nuove API grafiche.
Lo strato inferiore è un'astrazione sull'API grafica (Vulkan, Metal, Direct3D 12). Impeller non supporta OpenGL, poiché OpenGL non fornisce capacità per una compilazione offline efficiente degli shader. A questo livello sono implementati: gestione dei buffer dei vertici, creazione e caching delle pipeline (tubazioni grafiche) e sincronizzazione GPU. Una pipeline in Impeller è uno stato GPU precompilato che include shader, impostazioni di rasterizzazione e blending. Tutte le pipeline vengono create durante l'inizializzazione, eliminando la compilazione durante il rendering.
Lo strato intermedio è un sistema di gestione delle risorse. Alloca e riutilizza le risorse GPU: texture, buffer, campionatori. Invece di creare una nuova texture ogni frame, Impeller mantiene un pool di texture di varie dimensioni e formati. Il pool di memoria restituisce automaticamente le risorse inutilizzate e può espandersi quando necessario, ma senza la frammentazione caratteristica di Skia.
Lo strato superiore è il grafo di rendering, in cui Flutter Engine converte i comandi dell'API Canvas. Impeller riceve una Display List e costruisce da essa un grafo di dipendenze delle operazioni. Il grafo viene ottimizzato: i passaggi di rendering ridondanti vengono rimossi, le operazioni con lo stesso stato GPU vengono unite. Il grafo viene quindi compilato in una sequenza di chiamate Vulkan/Metal utilizzando pipeline pre-create.
Ogni frame attraversa una pipeline fissa: Display List → grafo di rendering → compilazione del grafo → invio dei comandi GPU. È possibile aggiungere passaggi aggiuntivi per post-effetti (sfocatura, ombre) o per la preparazione del buffer di profondità. Il tempo di frame in Impeller è più prevedibile che in Skia, poiché non ci sono ritardi non deterministici dovuti alla compilazione degli shader.
Il confronto tra Impeller e Skia mostra differenze nell'approccio al rendering. Skia è una libreria 2D universale per scopi generali, mentre Impeller è un motore specializzato per Flutter, ottimizzato per i requisiti dell'interfaccia utente mobile.
| Parametro | Skia | Impeller |
|---|---|---|
| Shader | Compilazione runtime | Compilazione offline (build time) |
| Shader jank | 50–200 ms al primo frame | Assente (0 ms) |
| Formato shader | Proprietario (SkSL) | SPIR-V (universale) |
| Backend GPU | OpenGL, Vulkan, Metal | Vulkan, Metal, Direct3D 12 |
| Consumo memoria | Alto (texture temporanee) | Pool di memoria, fino a -40% |
| Piattaforme | Android, iOS, Web, Desktop | Android, iOS, Desktop |
| Stato | Stabile (principale) | Preview (sostituzione Skia) |
La differenza principale è l'approccio agli shader. Skia compila gli shader al momento dell'utilizzo, creando shader jank durante il primo rendering di effetti sconosciuti. Impeller elimina questo problema attraverso la compilazione offline. Inoltre, Skia supporta OpenGL, necessario per la versione web di Flutter, ma Impeller abbandona OpenGL a favore di API più moderne, offrendo prestazioni migliori sui dispositivi mobili.
Per le applicazioni Flutter, il passaggio a Impeller non richiede modifiche al codice. Impeller implementa la stessa API Canvas di Skia, quindi tutti i widget, le animazioni e i disegni personalizzati funzionano in modo identico. La compatibilità all'indietro è garantita a livello di Flutter Engine — il motore seleziona il renderer (Skia o Impeller) durante l'inizializzazione dell'applicazione.
Impeller offre diversi vantaggi misurabili rispetto a Skia che influiscono direttamente sull'esperienza utente e sulle prestazioni delle applicazioni Flutter.
Lo shader jank è il problema principale di Skia che Impeller risolve completamente. Quando un'applicazione Flutter mostra un nuovo schermo con gradienti, maschere o blend non standard, Skia compila gli shader durante l'animazione, causando cadute di frame. Impeller compila tutti gli shader in fase di build, quindi il primo frame viene renderizzato velocemente come i successivi. Su dispositivi con GPU lenta (MediaTek Helio, Qualcomm serie 400), la differenza è particolarmente evidente — fino a 200 ms di ritardo per ogni nuovo tipo di effetto in Skia contro 0 ms in Impeller.
Impeller utilizza pool di risorse per gestire la memoria GPU. In Skia, ogni frame può creare nuove texture per superfici temporanee, specialmente quando si rende con trasparenza o si utilizza saveLayer. Impeller riutilizza le texture tra i frame, riducendo il consumo di picco di memoria del 30–40% su Android e fino al 25% su iOS. Questo è particolarmente importante per applicazioni con elenchi lunghi e animazioni, dove Skia poteva causare errori OOM su dispositivi con 2 GB di RAM.
In Skia, il tempo di rendering del frame può variare a seconda di quali shader sono già stati compilati. Il primo frame con un nuovo effetto può richiedere 50–200 ms, mentre i successivi richiedono 3–5 ms. Questa imprevedibilità rende difficile l'ottimizzazione e il testing. Impeller garantisce un tempo di frame costante, poiché tutti gli shader sono già compilati e l'allocazione della memoria è prevedibile. Flutter Engine con Impeller può calcolare più accuratamente il budget di tempo per ogni frame.
Impeller funziona direttamente con Vulkan (Android), Metal (iOS) e Direct3D 12 (Windows), senza il livello OpenGL. Questo offre diversi vantaggi: minore latenza del driver (fino al 50% in meno rispetto a OpenGL), controllo diretto sulla memoria GPU e accesso a funzionalità moderne (architettura GPU a tile, rendering guidato dalla GPU). OpenGL non si sta più evolvendo e i suoi driver sui dispositivi mobili diventano spesso un collo di bottiglia per le prestazioni.
Impeller è in fase di sviluppo attivo ed è disponibile nei canali Flutter Master e Beta. A partire da Flutter 3.16, Impeller è abilitato per impostazione predefinita su iOS e opzionalmente su Android tramite un flag di configurazione. La sostituzione completa di Skia con Impeller è prevista in una delle versioni stabili di Flutter del 2026.
Su iOS, Impeller funziona tramite Metal ed è abilitato per impostazione predefinita da Flutter 3.16. Il team Flutter consiglia di testare le applicazioni su Impeller e di segnalare eventuali problemi. Per tornare a Skia, utilizzare il flag Impeller nel file Info.plist: FlutterEnableImpeller = NO. Secondo Flutter Team, il 92% delle applicazioni iOS funziona su Impeller senza regressioni visibili e le prestazioni delle animazioni migliorano del 25–40%.
Su Android, Impeller funziona tramite Vulkan. Per abilitarlo, aggiungere il meta-tag io.flutter.embedded_views_preview in AndroidManifest.xml. Il team Flutter continua a ottimizzare Impeller per varie architetture GPU (Adreno, Mali, PowerVR). La sfida principale su Android è il supporto di dispositivi senza Vulkan (Android < 7.0 o GPU vecchie). Per tali dispositivi, verrà utilizzato un backend di fallback basato su Skia o Impeller con rasterizzazione software.
Su Windows, Impeller funziona tramite Direct3D 12 (abilitato in Flutter Master). Su macOS e Linux — tramite Metal e Vulkan rispettivamente. Impeller non è previsto per il Web, poiché la versione web di Flutter utilizza CanvasKit (Skia tramite WebAssembly) e lo shader jank non è un problema critico per essa a causa di un diverso meccanismo di compilazione degli shader nel browser. La versione web continuerà a utilizzare Skia.
Google ha pubblicato la roadmap di Impeller: 2024 — Impeller predefinito su iOS; 2025 — Impeller predefinito su Android e Windows; 2026 — rimozione completa di Skia da Flutter Engine. Successivamente, Flutter utilizzerà Impeller come unico motore di rendering, semplificando la manutenzione, riducendo le dimensioni del motore e migliorando le prestazioni su tutte le piattaforme.
Domande frequenti
Su iOS, Impeller è abilitato per impostazione predefinita da Flutter 3.16. Su Android, aggiungere il meta-tag io.flutter.embedded_views_preview con valore true in AndroidManifest.xml. Su Windows, utilizzare il flag --enable-impeller all'avvio. In tutti i casi, è possibile forzare l'abilitazione tramite FlutterEngine nel codice Dart.
Skia funziona, ma ha problemi fondamentali: shader jank (50–200 ms di ritardo nella compilazione degli shader), consumo elevato di memoria e limitazioni dell'architettura OpenGL. Impeller è progettato specificamente per Flutter e risolve questi problemi attraverso la compilazione offline degli shader e i pool di memoria.
Sì, Impeller implementa la stessa API Canvas di Skia. Tutti i widget standard di Flutter — testo, immagini, animazioni, disegni personalizzati — funzionano su Impeller senza modifiche. La compatibilità all'indietro è garantita a livello di Flutter Engine e la transizione è trasparente per lo sviluppatore.
No, un'applicazione utilizza un motore di rendering alla volta. La scelta viene effettuata durante l'inizializzazione di Flutter Engine tramite un flag. Il passaggio tra Skia e Impeller durante l'esecuzione dell'applicazione è impossibile — il renderer viene fissato fino alla creazione della prima istanza di FlutterEngine.
Skia continuerà ad esistere come libreria indipendente di Google per Chrome, Android e altri progetti. In Flutter, Skia verrà sostituita da Impeller come renderer principale. Skia rimarrà per la versione web di Flutter (tramite CanvasKit) e come opzione di fallback per dispositivi senza supporto Vulkan/Metal.
Riepilogo
Svilupperemo un'applicazione mobile chiavi in mano
IT Sectr crea applicazioni iOS e Android per startup e aziende dal 2017. Ti consulteremo e ti proporremo la soluzione migliore.