Cos'è Impeller

Impeller è il motore di rendering che ha sostituito Skia come backend grafico predefinito di Flutter. A partire da Flutter 3.10 è attivo per impostazione predefinita su iOS, mentre dalla versione 3.27 è diventato il rendering di default anche su Android (con dispositivi Vulkan-capable), lasciando Skia come fallback.

La motivazione principale dietro Impeller è risolvere uno dei problemi storici di Flutter: lo shader jank. Con Skia, i frame potevano risultare a scatti la prima volta che un particolare effetto grafico veniva mostrato, perché lo shader corrispondente doveva essere compilato a runtime. Questo generava micro-stuttering fastidioso, soprattutto durante le animazioni.

Come Impeller elimina lo shader jank

La strategia di Impeller è compilare gli shader in fase di build anziché a runtime. Invece di generare shader dinamicamente durante l'esecuzione, Impeller utilizza un set predefinito e ridotto di shader, compilati offline durante la build dell'engine. Questo significa che al primo utilizzo di un effetto non c'è alcuna pausa per la compilazione.

Impeller sfrutta le API grafiche moderne native di ogni piattaforma:

  • Metal su iOS e macOS
  • Vulkan su Android (con fallback OpenGL ove necessario)
  • Supporto sperimentale anche per altre piattaforme

Verificare quale motore è in uso

Su Android puoi disattivare esplicitamente Impeller (per debugging o compatibilità) modificando il file AndroidManifest.xml:

<application ...>
    <meta-data
        android:name="io.flutter.embedding.android.EnableImpeller"
        android:value="false" />
</application>

Su iOS l'equivalente si configura nel file Info.plist:

<key>FLTEnableImpeller</key>
<false/>

Inoltre puoi forzare o disabilitare Impeller da riga di comando durante lo sviluppo:

# Disabilita Impeller
flutter run --no-enable-impeller

# Abilita Impeller esplicitamente
flutter run --enable-impeller

Impatto sui custom shader

Se nella tua app usi shader personalizzati tramite FragmentProgram, Impeller li supporta ma con alcune differenze rispetto a Skia. Gli shader vanno dichiarati nel pubspec.yaml:

flutter:
  shaders:
    - shaders/ripple.frag

E caricati nel codice Dart:

import 'dart:ui';

Future<FragmentShader> loadShader() async {
  final program = await FragmentProgram.fromAsset('shaders/ripple.frag');
  return program.fragmentShader();
}

È importante ricordare che Impeller supporta un sottoinsieme più ristretto di GLSL rispetto a Skia. Alcune funzionalità avanzate degli shader potrebbero comportarsi in modo diverso, quindi è sempre bene testare i custom shader su entrambi i motori.

Testare le performance

Per verificare i benefici reali di Impeller nella tua app, usa il profiling in modalità profile:

flutter run --profile

Apri il DevTools e analizza la scheda Performance. Cerca eventuali frame che superano i 16 ms (per 60 fps) o gli 8 ms (per 120 fps). Con Impeller, i picchi legati alla compilazione degli shader al primo rendering dovrebbero essere assenti.

Buone pratiche con Impeller

  • Testa sempre in modalità profile o release: la modalità debug non riflette le reali performance del rendering.
  • Verifica i dispositivi Android più vecchi: se un dispositivo non supporta Vulkan, Impeller potrebbe usare un fallback OpenGL con performance diverse.
  • Segnala i bug grafici: durante la transizione da Skia, alcuni effetti (blur, gradienti complessi) possono rendere in modo leggermente diverso. Il team Flutter è attivo nel raccogliere feedback su GitHub.
  • Non abusare degli effetti costosi: BackdropFilter e blur restano operazioni onerose anche con Impeller; usali con parsimonia nelle liste scrollabili.

Conclusione

Impeller rappresenta un cambiamento profondo nell'architettura grafica di Flutter, mirato a offrire animazioni fluide e prevedibili fin dal primo frame. Con la sua adozione come motore predefinito su iOS e Android, la maggior parte degli sviluppatori ne trae beneficio senza modifiche al codice. Conoscerne il funzionamento aiuta però a diagnosticare eventuali differenze di rendering e a sfruttare al meglio il nuovo pipeline grafico.