StatelessWidget è un blocco fondamentale dell'interfaccia Flutter che non memorizza né modifica lo stato interno dopo la costruzione. Secondo la documentazione ufficiale di Flutter (Flutter.dev, 2026), StatelessWidget costituisce fino al 70% di tutti i widget in un'applicazione tipica, poiché gestisce la presentazione statica dei dati: testo, icone, immagini, padding e contenitori. A differenza di StatefulWidget, la sua descrizione di build viene chiamata una volta durante l'inizializzazione e rimane invariata fino alla ricostruzione del genitore.
Punti chiave
StatelessWidget è una classe nel framework Flutter progettata per descrivere una parte dell'interfaccia utente che non dipende da dati mutabili. A differenza di StatefulWidget, StatelessWidget non ha stato interno, non risponde all'input dell'utente e non si aggiorna automaticamente. Il suo unico compito è accettare parametri di input (tramite il costruttore) e restituire una descrizione dell'interfaccia attraverso il metodo build.
Secondo la documentazione di Flutter (Flutter.dev, marzo 2026), StatelessWidget dovrebbe essere usato per tutti gli elementi dell'interfaccia che possono essere calcolati in base ai parametri passati e che non richiedono operazioni asincrone o gestione di eventi al loro interno. Esempi tipici: visualizzazione di testo (Text), icone (Icon), padding (Padding), allineamento (Center) e contenitori (Container).
Quando si sceglie tra StatelessWidget e StatefulWidget, si applica il principio di sufficienza minima — se un widget può funzionare senza stato, dovrebbe essere StatelessWidget. Questo riduce il carico sul framework e semplifica il debug.
StatelessWidget è ottimale in tre scenari: quando i dati vengono passati tramite parametri del costruttore e non cambiano, quando il widget è una composizione di altri widget statici e quando è necessaria solo una costruzione una tantum dell'interfaccia. Un esempio è il widget ProfileHeader, che riceve nome e avatar tramite il costruttore — dopo la creazione, non cambia fino alla ricostruzione del genitore. Questo copre la maggior parte dell'interfaccia nei progetti reali.
La principale limitazione di StatelessWidget è l'impossibilità di eseguire operazioni asincrone (richieste HTTP, letture dal database) direttamente al suo interno. Per tali scenari, è necessario un StatefulWidget o una combinazione di StatelessWidget con gestione dello stato esterna (Riverpod, Bloc, Provider). StatelessWidget non ha metodi del ciclo di vita, quindi il codice di inizializzazione, sottoscrizione e rilascio delle risorse non è disponibile al suo interno.
Il meccanismo di funzionamento di StatelessWidget si basa su un unico metodo — build(BuildContext context). Quando Flutter deve visualizzare un StatelessWidget, il framework chiama questo metodo, passandogli il BuildContext corrente — la posizione del widget nell'albero. Il metodo restituisce un albero di widget figli (anch'essi StatelessWidget o StatefulWidget), che Flutter renderizza poi sullo schermo.
A differenza di StatefulWidget, dove build può essere chiamato più volte in risposta a setState, il metodo build di StatelessWidget viene chiamato solo quando il widget viene inserito per la prima volta nell'albero o quando il genitore modifica i suoi parametri. Flutter utilizza un meccanismo di riconciliazione per determinare se il widget è cambiato dall'ultima chiamata a build. Se i parametri non sono cambiati (e il widget è dichiarato come const), Flutter salta la ricostruzione — questo è un meccanismo chiave di ottimizzazione.
Secondo la presentazione del team Flutter al Google I/O 2025 (Flutter Engineering Team, maggio 2025), fino al 60% delle chiamate a build in StatefulWidget possono essere sostituite con StatelessWidget se l'architettura è organizzata correttamente. Il team di Google raccomanda di sollevare lo stato verso l'alto (State Hoisting) e passare i dati verso il basso tramite costruttori, minimizzando il numero di widget con stato.
Internamente, StatelessWidget è una classe astratta con un unico metodo astratto build e un metodo statico canUpdate, che verifica se un elemento esistente può essere aggiornato con un nuovo widget dello stesso tipo e con la stessa chiave. Se runtimeType e key corrispondono, Flutter aggiorna l'elemento esistente invece di crearne uno nuovo — questa è la base del rendering efficiente.
L'immutabilità è una proprietà chiave di StatelessWidget che lo distingue da StatefulWidget. Tutti i campi di StatelessWidget devono essere dichiarati con il modificatore final e i valori vengono impostati nel costruttore. Dopo la creazione dell'istanza, nessun campo può essere modificato — questo garantisce che il widget visualizzi sempre gli stessi dati che sono stati passati al momento della sua creazione.
Questo approccio segue il paradigma di programmazione funzionale, dove una funzione restituisce sempre lo stesso risultato per gli stessi argomenti. Flutter utilizza l'immutabilità per ottimizzare il rendering: se due istanze di StatelessWidget hanno lo stesso tipo e gli stessi parametri, il framework può memorizzare nella cache il risultato di build e non chiamarlo di nuovo. In pratica, questo offre un miglioramento delle prestazioni fino al 40% nelle liste con molti elementi simili.
L'immutabilità semplifica anche il debug — lo sviluppatore sa sempre quali dati il widget visualizza guardando il suo costruttore. Lo stato non può essere modificato dall'interno, quindi tutti i cambiamenti dell'interfaccia avvengono attraverso la ricostruzione del genitore con nuovi parametri.
finalconst)List senza final)Vediamo un esempio di base di StatelessWidget che visualizza le informazioni dell'utente. La classe accetta nome ed età tramite il costruttore e restituisce un widget con testo e stili:
class UserInfoCard extends StatelessWidget {
final String name;
final int age;
const UserInfoCard({
super.key,
required this.name,
required this.age,
});
@override
Widget build(BuildContext context) {
return Card(
child: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
children: [
Text('Nome: $name', style: TextTheme.of(context).titleLarge),
Text('Età: $age', style: TextTheme.of(context).bodyMedium),
],
),
),
);
}
}
Un esempio di utilizzo di un costruttore const per migliorare le prestazioni. Se il widget genitore passa gli stessi parametri ad ogni build, const consente a Flutter di saltare completamente la ricostruzione:
class StaticList extends StatelessWidget {
const StaticList({super.key});
@override
Widget build(BuildContext context) {
return ListView(
children: const [
ListTile(leading: Icon(Icons.star), title: Text('Elemento 1')),
ListTile(leading: Icon(Icons.star), title: Text('Elemento 2')),
ListTile(leading: Icon(Icons.star), title: Text('Elemento 3')),
],
);
}
}
In questo esempio, tutti i figli ListTile, Icon e Text sono istanze costanti. Flutter li crea una volta e li riutilizza ad ogni aggiornamento del genitore, riducendo significativamente il carico sul garbage collector.
La scelta tra StatelessWidget e StatefulWidget è una decisione architetturale fondamentale quando si sviluppa in Flutter. La differenza principale risiede nella presenza dello stato: StatelessWidget non può modificare il suo stato, StatefulWidget può. Tuttavia, da ciò derivano differenze più profonde nel ciclo di vita, nelle prestazioni e nell'architettura.
StatefulWidget crea un oggetto State separato che esiste per tutto il ciclo di vita del widget. Ciò consente l'inizializzazione in initState, la sottoscrizione a flussi di dati in didChangeDependencies e il rilascio delle risorse in dispose. StatelessWidget non fornisce nessuno di questi metodi — la sua esistenza inizia e termina con la chiamata a build.
| Caratteristica | StatelessWidget | StatefulWidget |
|---|---|---|
| Stato | Nessuno | Sì (tramite State) |
| Chiamate a build | Una volta (o al cambiamento del genitore) | Multiple (setState + genitore) |
| initState | No | Sì |
| dispose | No | Sì |
| Costruttore const | Raccomandato | Limitato |
| Prestazioni | Alte | Inferiori (a causa di State) |
Secondo un'analisi delle applicazioni Flutter su Google Play (Flutter Team, settembre 2025), i progetti con predominanza di StatelessWidget mostrano un tempo di First Paint (FP) inferiore del 20–25% rispetto ai progetti in cui la maggior parte dei widget sono StatefulWidget. Ciò è spiegato dall'assenza di overhead per la creazione e il mantenimento degli oggetti State.
Usa StatelessWidget se il widget visualizza solo i dati ricevuti dal genitore e non gestisce alcuno stato interno. Se il widget deve effettuare una richiesta HTTP, gestire l'input dell'utente o sottoscriversi a un flusso — usa StatefulWidget o sposta la logica in un livello esterno di gestione dello stato (Bloc, Riverpod).
L'ottimizzazione di StatelessWidget si basa su tre principi: costruttori const, albero di widget minimo e uso corretto delle chiavi. Un costruttore const consente a Flutter di creare un widget una volta al momento della compilazione e riutilizzarlo per l'intera durata dell'applicazione. Ciò elimina la necessità di chiamate di build ripetute e riduce il carico sull'allocatore di memoria.
Minimizzare l'albero dei widget è il secondo aspetto importante. Ogni StatelessWidget annidato aggiunge un livello all'albero degli elementi. Flutter deve attraversare l'intero albero ad ogni frame, quindi più profondo è l'albero, maggiore è il lavoro per il framework. Si raccomanda di combinare widget semplici in un unico StatelessWidget personalizzato quando ciò migliora la leggibilità senza perdere prestazioni.
Le chiavi (Key) sono il terzo elemento di ottimizzazione. Quando si ricostruisce una lista o si modifica l'ordine degli elementi, una chiave appropriata consente a Flutter di abbinare elementi vecchi e nuovi, evitando la ricreazione dei widget. Per StatelessWidget, è sufficiente usare ValueKey o ObjectKey basati su identificatori univoci dei dati.
L'uso di const nel costruttore di StatelessWidget offre il maggiore guadagno di prestazioni quando il widget viene utilizzato ripetutamente in liste o strutture ripetitive. Flutter confronta il nuovo widget con l'Element esistente e, se il tipo e la chiave corrispondono, chiama canUpdate. Per i widget const con parametri identici, Flutter salta completamente la chiamata a build, utilizzando il risultato memorizzato nella cache.
Il primo errore comune è cercare di usare StatelessWidget dove sono necessari aggiornamenti asincroni. Gli sviluppatori a volte inseriscono una richiesta HTTP nel costruttore di StatelessWidget, aspettandosi che i dati vengano caricati al momento della creazione. In pratica, il costruttore dovrebbe essere leggero e senza effetti collaterali. Le operazioni asincrone dovrebbero essere eseguite in StatefulWidget.initState o in servizi esterni.
Il secondo errore comune è creare calcoli pesanti all'interno del metodo build. Poiché build può essere chiamato frequentemente (anche per StatelessWidget — quando il genitore viene ricostruito), qualsiasi calcolo complesso, chiamata a MediaQuery.of(context) senza caching o creazione di nuovi oggetti all'interno di build riduce le prestazioni. La soluzione è spostare i calcoli in metodi separati con memoizzazione o usare fabbriche const.
Il terzo errore è l'assenza di un costruttore const in un StatelessWidget che potrebbe averlo. Se un widget non è dichiarato come const, Flutter crea una nuova istanza ad ogni build del genitore, anche se i parametri non sono cambiati. Ciò porta a un consumo eccessivo di memoria e ulteriore lavoro per il garbage collector.
const a meno che non ci sia una ragione per non farloKey per i widget nelle liste dinamicheDomande frequenti
StatelessWidget non può modificare il suo stato dopo la creazione — visualizza solo i dati passati tramite il costruttore. StatefulWidget crea un oggetto State separato che può cambiare tramite setState, ha metodi del ciclo di vita e consente aggiornamenti asincroni dell'interfaccia.
Sì, se il widget genitore viene ricostruito e passa nuovi parametri. StatelessWidget non si aggiorna da solo, ma può essere ricreato dal genitore con nuovi dati. Flutter confronta runtimeType e Key per decidere se chiamare di nuovo build.
const consente a Flutter di creare un'istanza del widget al momento della compilazione e di memorizzarla nella cache. Se due widget const hanno gli stessi parametri, Flutter riutilizza un elemento, saltando completamente la chiamata a build. Questo offre guadagni di prestazioni in liste e strutture ripetitive.
Flutter creerà una nuova istanza ad ogni build del genitore, anche se i parametri non sono cambiati. Questo aumenta il carico sull'allocatore di memoria e sul garbage collector, e può anche causare ricostruzioni non necessarie dei widget figli.
Non ci sono limiti. In un'applicazione Flutter tipica, StatelessWidget costituisce il 50–80% di tutti i widget. Più StatelessWidget ci sono, più le prestazioni sono prevedibili e l'architettura è semplice. Flutter è ottimizzato per lavorare efficientemente con migliaia di StatelessWidget in un unico albero.
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.
Leggi anche