[{"data":1,"prerenderedAt":27},["ShallowReactive",2],{"articolo-grafica-vettoriale-e-asset-in-flutter-guida-a-flutter-svg-e-vector-graphics":3,"comments-article-grafica-vettoriale-e-asset-in-flutter-guida-a-flutter-svg-e-vector-graphics":26},{"id":4,"title":5,"slug":6,"excerpt":7,"body":8,"cover_image":9,"cover_remote_url":10,"cover_credit":11,"video_url":15,"status":16,"published_at":17,"meta_title":18,"meta_description":19,"category":20,"author":24},94,"Grafica vettoriale e asset in Flutter: guida a flutter_svg e vector_graphics","grafica-vettoriale-e-asset-in-flutter-guida-a-flutter-svg-e-vector-graphics","Flutter non supporta gli SVG in modo nativo: ecco come gestirli con flutter_svg, come precompilarli in formato .vec con vector_graphics per guadagnare performance e come organizzare gli asset di progetto in modo type-safe.","## Perché parlare di SVG in Flutter\n\nA differenza del web o di Android (che ha i `VectorDrawable`), il framework Flutter **non sa disegnare un file SVG nativamente**: `Image.asset()` accetta PNG, JPEG, WebP, GIF e BMP, ma non XML vettoriale. Eppure gli asset vettoriali sono spesso la scelta migliore: un solo file scala perfettamente su ogni densità di schermo, pesa pochi KB e può essere ricolorato a runtime per seguire il tema dell'app.\n\nLa soluzione di riferimento è il pacchetto [`flutter_svg`](https:\u002F\u002Fpub.dev\u002Fpackages\u002Fflutter_svg), che dalla versione 2.x è stato riscritto sopra `vector_graphics`, il motore ufficiale mantenuto dal team Flutter. Vediamo come usarlo bene, quali sono i suoi limiti e come spremerne le performance con la precompilazione degli asset.\n\n## Installazione e primo utilizzo\n\n```yaml\ndependencies:\n  flutter_svg: ^2.0.10\n  vector_graphics: ^1.1.11\n\ndev_dependencies:\n  vector_graphics_compiler: ^1.1.11\n```\n\nRicorda di dichiarare la cartella degli asset nel `pubspec.yaml`:\n\n```yaml\nflutter:\n  assets:\n    - assets\u002Ficons\u002F\n```\n\nIl widget base è `SvgPicture`, disponibile in quattro costruttori (`asset`, `network`, `file`, `string`):\n\n```dart\nimport 'package:flutter_svg\u002Fflutter_svg.dart';\n\nSvgPicture.asset(\n  'assets\u002Ficons\u002Flogo.svg',\n  width: 120,\n  height: 120,\n  fit: BoxFit.contain,\n  semanticsLabel: 'Logo aziendale',\n);\n```\n\nA differenza di `Image`, `SvgPicture` **non ha una dimensione intrinseca garantita**: se non specifichi `width`\u002F`height` il widget prova a occupare lo spazio concesso dal parent. Dentro una `Row` o una `Column` senza vincoli è la prima causa di layout \"che esplodono\": conviene sempre wrappare in un `SizedBox` o passare dimensioni esplicite.\n\n## Ricolorare un SVG in base al tema\n\nNelle vecchie versioni si usava il parametro `color`, oggi deprecato in favore di `colorFilter`, che è più esplicito sul `BlendMode` applicato:\n\n```dart\nSvgPicture.asset(\n  'assets\u002Ficons\u002Fheart.svg',\n  width: 24,\n  colorFilter: ColorFilter.mode(\n    Theme.of(context).colorScheme.primary,\n    BlendMode.srcIn,\n  ),\n);\n```\n\n`BlendMode.srcIn` sostituisce tutti i colori del disegno mantenendo l'alpha: è quello che serve nel 95% dei casi per le icone monocromatiche. Se invece l'SVG è multicolore (un'illustrazione, un logo) non applicare filtri.\n\nUn pattern comodo è incapsulare tutto in un widget riutilizzabile, così da non ripetere la stessa configurazione in decine di punti:\n\n```dart\nclass AppIcon extends StatelessWidget {\n  const AppIcon(this.name, {super.key, this.size = 24, this.color});\n\n  final String name;\n  final double size;\n  final Color? color;\n\n  @override\n  Widget build(BuildContext context) {\n    final tint = color ?? IconTheme.of(context).color;\n    return SvgPicture.asset(\n      'assets\u002Ficons\u002F$name.svg',\n      width: size,\n      height: size,\n      colorFilter: tint == null\n          ? null\n          : ColorFilter.mode(tint, BlendMode.srcIn),\n    );\n  }\n}\n```\n\nCosì `AppIcon('heart')` eredita automaticamente il colore dell'`IconTheme` corrente, esattamente come farebbe un `Icon` di Material.\n\n## Placeholder, errori e SVG remoti\n\nGli SVG caricati da rete richiedono un attimo per arrivare e vanno gestiti come qualsiasi risorsa asincrona:\n\n```dart\nSvgPicture.network(\n  'https:\u002F\u002Fexample.com\u002Fbadge.svg',\n  width: 64,\n  placeholderBuilder: (context) => const SizedBox(\n    width: 64,\n    height: 64,\n    child: Center(child: CircularProgressIndicator(strokeWidth: 2)),\n  ),\n);\n```\n\nAttenzione: `SvgPicture.network` mantiene una cache in memoria ma **non** una cache su disco. Se gli SVG remoti sono centrali nella tua UI, scaricali con Dio\u002F`http` e passali a `SvgPicture.memory`, oppure usa un `BytesLoader` personalizzato che legge da una cache su file system.\n\n## Precompilare gli SVG con vector_graphics\n\nQui arriva la parte interessante in termini di performance. Quando carichi un `.svg`, a runtime l'app deve: leggere l'asset, fare il parsing dell'XML, risolvere gradienti\u002Ftrasformazioni\u002Fpath e costruire la lista di comandi di disegno. Su icone semplici è irrilevante, su illustrazioni complesse o su liste con molti elementi diventa jank visibile.\n\n`vector_graphics_compiler` sposta tutto questo lavoro al **build time**, producendo un formato binario `.vec` già ottimizzato (path semplificati, mask risolte, comandi pronti per il canvas).\n\n```bash\n# singolo file\ndart run vector_graphics_compiler -i assets\u002Ficons\u002Flogo.svg -o assets\u002Fvec\u002Flogo.vec\n\n# batch su una cartella\nfor f in assets\u002Ficons\u002F*.svg; do\n  name=$(basename \"$f\" .svg)\n  dart run vector_graphics_compiler -i \"$f\" -o \"assets\u002Fvec\u002F$name.vec\"\ndone\n```\n\nAggiungi `assets\u002Fvec\u002F` al `pubspec.yaml` e carica i file compilati con un `BytesLoader`:\n\n```dart\nimport 'package:vector_graphics\u002Fvector_graphics.dart';\n\nconst logoLoader = AssetBytesLoader('assets\u002Fvec\u002Flogo.vec');\n\nVectorGraphic(\n  loader: logoLoader,\n  width: 120,\n  colorFilter: const ColorFilter.mode(Colors.indigo, BlendMode.srcIn),\n);\n```\n\nPuoi anche continuare a usare `SvgPicture`, che accetta direttamente un loader:\n\n```dart\nSvgPicture(logoLoader, width: 120);\n```\n\nUn consiglio pratico: integra la compilazione nella pipeline CI (o in uno script `tool\u002Fbuild_icons.sh`) e committa i `.vec`, oppure genera i file in fase di build e tienili fuori dal repository. L'importante è che il team non debba ricordarsi di lanciare il comando a mano.\n\n## Precaching: evitare il \"lampo\" al primo frame\n\nAnche con i `.vec`, il primo caricamento di un asset avviene in modo asincrono e per un frame vedi lo spazio vuoto. Per le schermate critiche (splash, onboarding, home) conviene fare precaching:\n\n```dart\nFuture\u003Cvoid> precacheVectors() async {\n  const loaders = \u003CBytesLoader>[\n    AssetBytesLoader('assets\u002Fvec\u002Flogo.vec'),\n    AssetBytesLoader('assets\u002Fvec\u002Fempty_state.vec'),\n  ];\n\n  for (final loader in loaders) {\n    await svg.cache.putIfAbsent(\n      loader.cacheKey(null),\n      () => loader.loadBytes(null),\n    );\n  }\n}\n```\n\nChiamalo dopo `WidgetsFlutterBinding.ensureInitialized()` in `main()`, oppure in `didChangeDependencies` della schermata precedente.\n\n## Cosa non funziona: i limiti da conoscere\n\n`flutter_svg` supporta un sottoinsieme ampio ma non completo della specifica SVG. In particolare **non** sono supportati (o lo sono solo parzialmente):\n\n- animazioni SMIL (`\u003Canimate>`, `\u003CanimateTransform>`);\n- script e CSS esterni;\n- la maggior parte dei filtri (`\u003Cfilter>`, blur gaussiani complessi);\n- l'elemento `\u003Ctext>`, che va convertito in path prima dell'export.\n\nLa regola d'oro è: **esporta sempre l'SVG con testo convertito in tracciati** e fai passare i file da un ottimizzatore come SVGO prima di importarli. Un SVG esportato \"grezzo\" da Figma o Illustrator può contenere migliaia di nodi inutili e gruppi annidati che pesano sul rendering. Se il compiler segnala warning, è il momento di semplificare il file a monte, non di combattere con il codice Dart.\n\n## Il resto degli asset: densità, tree-shaking e type-safety\n\nGli SVG non risolvono tutto: foto e texture restano raster. Per quelli, ricorda le **asset variants** basate sulla densità dello schermo:\n\n```\nassets\u002Fimages\u002Fhero.png        # 1x\nassets\u002Fimages\u002F2.0x\u002Fhero.png\nassets\u002Fimages\u002F3.0x\u002Fhero.png\n```\n\nNel `pubspec.yaml` dichiari solo `assets\u002Fimages\u002Fhero.png`: Flutter sceglie la variante giusta in base al `devicePixelRatio`. E quando mostri un'immagine molto più grande dello spazio in cui verrà disegnata, usa `cacheWidth`\u002F`cacheHeight` per decodificarla già ridimensionata e risparmiare memoria:\n\n```dart\nImage.asset('assets\u002Fimages\u002Fhero.png', cacheWidth: 800);\n```\n\nPer le icone dei font (Material Icons, Cupertino Icons) Flutter applica automaticamente il **tree-shaking**: nelle build di release include solo i glifi effettivamente usati, purché tu non costruisca `IconData` dinamicamente da un code point.\n\nInfine, per eliminare le stringhe magiche sui percorsi, vale la pena aggiungere [`flutter_gen`](https:\u002F\u002Fpub.dev\u002Fpackages\u002Fflutter_gen):\n\n```yaml\ndev_dependencies:\n  build_runner: ^2.4.0\n  flutter_gen_runner: ^5.4.0\n\nflutter_gen:\n  integrations:\n    flutter_svg: true\n```\n\nDopo `dart run build_runner build` puoi scrivere:\n\n```dart\nAssets.icons.heart.svg(width: 24);\nAssets.images.hero.image(fit: BoxFit.cover);\n```\n\nNiente più refusi nei path e un errore di compilazione — invece di un crash a runtime — se rinomini o cancelli un file.\n\n## Checklist finale\n\n- Usa SVG per icone e illustrazioni, raster solo per foto e texture.\n- Ricolora con `colorFilter` + `BlendMode.srcIn`, mai con il deprecato `color`.\n- Dai sempre vincoli di dimensione a `SvgPicture`.\n- Precompila in `.vec` con `vector_graphics_compiler` gli asset complessi o usati in liste.\n- Fai precaching degli asset visibili nei primi frame.\n- Ottimizza i file a monte (SVGO, testo convertito in path).\n- Genera i path con `flutter_gen` per avere asset type-safe.\n\nCon queste accortezze la grafica vettoriale in Flutter diventa un vantaggio netto: meno MB nel bundle, nessuna icona sgranata su nessun display e una UI che cambia colore insieme al tema senza duplicare un solo file.","https:\u002F\u002Fflutter.it\u002Fstorage\u002Farticles\u002Ff2d0c989-9056-461f-8883-317c559d4d51.jpg","https:\u002F\u002Fimages.unsplash.com\u002Fphoto-1623841675698-8aac12636480?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=M3w5NzA2NTJ8MHwxfHJhbmRvbXx8fHx8fHx8fDE3ODkwOTkyOTJ8&ixlib=rb-4.1.0&q=80&w=1080",{"name":12,"author_url":13,"photo_url":14},"Viktor Forgacs","https:\u002F\u002Funsplash.com\u002F@sonance","https:\u002F\u002Funsplash.com\u002Fphotos\u002Fblack-and-white-zebra-pattern-textile-uiuqB_v8Trg",null,"published","2026-09-11T04:01:33+00:00","SVG in Flutter con flutter_svg e vector_graphics","Come usare gli SVG in Flutter con flutter_svg: colorFilter, placeholder, precompilazione in .vec con vector_graphics, precaching e gestione degli asset.",{"id":21,"name":22,"slug":23},1,"Guide","guide",{"id":21,"name":25},"Flutter Bot",[],1789120576729]