In Flutter, when should brand SVGs render through flutter_svg's SvgPicture versus precompiled vector_graphics, and what does each cost at runtime?
answer
- parse on device or at build time
- flutter_svg is built on vector_graphics
- compute in release, main isolate in debug
- a binary file and AssetBytesLoader
- raster versus picture strategy
basics
~20 sSvgPicture parses SVG XML on the device and caches the result; precompiling with vector_graphics_compiler moves parsing and path optimisation to build time, so VectorGraphic only decodes a compact binary. Precompile static brand art; parse at runtime only SVGs that arrive later.
solid answer
~40 s`flutter_svg` 2.x sits on top of `vector_graphics`: `SvgPicture.asset`, `.network` and `.string` parse the XML on the device with the `vector_graphics_compiler` library, in a background isolate via `compute` in profile and release (on the main isolate in debug and on the web), with the clip, mask and overdraw optimisers switched off, then keep the encoded bytes in `svg.cache` (100 entries by default). Precompiling runs the same compiler at build time — the `dart run vector_graphics_compiler` CLI or an asset transformer — and ships a binary that `VectorGraphic(loader: AssetBytesLoader(...))` or `SvgPicture(AssetBytesLoader(...))` only decodes, with optimisations on and unsupported SVG features (filters, some text attributes) caught at build time. So static brand icons and illustrations should be precompiled; SVGs fetched from a server must be parsed at runtime. Single-colour art can be tinted with `colorFilter: ColorFilter.mode(color, BlendMode.srcIn)`.
code
dart · 28 linesimport 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:vector_graphics/vector_graphics.dart';
class ClinicHeader extends StatelessWidget {
const ClinicHeader({super.key, required this.promoUrl});
final String promoUrl;
@override
Widget build(BuildContext context) {
return Column(
children: <Widget>[
// Static brand art: precompiled at build time.
const VectorGraphic(
loader: AssetBytesLoader('assets/clinic_logo.svg.vec'),
width: 160,
),
// Arrives from the server: parsed on the device.
SvgPicture.network(
promoUrl,
height: 80,
colorFilter: ColorFilter.mode(Theme.of(context).colorScheme.primary, BlendMode.srcIn),
),
],
);
}
}go deeper
Know that Flutter needs a package for SVG and that SvgPicture.asset displays one from the assets.
Explain runtime parsing versus build-time compilation, and how colorFilter tints single-colour SVGs.
Choose precompiled assets for static art, tune rendering strategy for heavy graphics, and catch unsupported SVG features in CI.
Set the asset pipeline policy: which formats designers deliver, where compilation runs, and how server-delivered vectors are validated.
## Why SVG at all A pet-clinic app's multi-colour brand marks — a clinic logo, an illustrated empty state with a sleeping cat — cannot be icon-font glyphs, which are one colour each. **SVG** keeps them resolution-independent without shipping a PNG per density. Flutter has no built-in SVG widget; the two maintained options are both in the `flutter/packages` repository and share one engine. ## How flutter_svg renders an SVG `flutter_svg` 2.x is a front end to `vector_graphics`. For `SvgPicture.asset`, `SvgPicture.network`, `SvgPicture.string` and friends: 1. The loader reads the XML (from the asset bundle, the network, a string). 2. It calls the `vector_graphics_compiler` library's `encodeSvg` to parse the XML and encode it into the vector_graphics binary format. In profile and release builds this runs in a background isolate via `compute`; in debug builds and on the web it runs on the main isolate. 3. The runtime parse turns the clipping, masking and overdraw **optimisers off**. 4. The encoded bytes go into `svg.cache`, keyed by the source and theme, holding **100 entries** by default. 5. `vector_graphics` decodes the bytes and draws them. Every first display of an SVG therefore pays an XML parse on the device. ## How precompiled vector_graphics renders Precompiling moves steps 1-3 to build time. Either run the compiler yourself: ```bash dart run vector_graphics_compiler -i assets/clinic_logo.svg -o assets/clinic_logo.svg.vec ``` or attach it as an asset transformer so the build converts the SVG as it copies it (configuring that is covered with asset declaration). The app then loads the binary: ```dart const Widget logo = VectorGraphic(loader: AssetBytesLoader('assets/clinic_logo.svg.vec')); ``` `SvgPicture(AssetBytesLoader(...))` accepts the same binary, which eases migration. The build-time compile enables **path optimisations** (opacity peepholing, transform inlining, group collapsing, mask and clip elimination) and fails fast on features the format does not support, such as SVG **filters** and some text-processing attributes — better found in CI than on a user's screen. `AssetBytesLoader` does not cache bytes itself. ## Rendering strategy Both widgets can draw as a **picture** (replaying vector commands) or a **raster** (an image drawn once and reused frame to frame): | Widget | Default strategy | |---|---| | `SvgPicture` constructors | `RenderingStrategy.picture` (via `renderingStrategy`) | | `VectorGraphic(...)` public constructor | `RenderingStrategy.raster` | The package docs recommend raster for very large or complex graphics used as backdrops at fixed scales, and picture for icon-like or small graphics. ## Choosing | Source | Best fit | Why | |---|---|---| | One-colour icons | icon font | tints with `IconTheme`, one file for the set | | Static brand SVGs in the app | precompiled `vector_graphics` | no parse on device, optimised paths, build-time errors | | SVGs fetched at runtime | `SvgPicture.network` | only a runtime parse is possible | | Photos | raster images | vectors cannot represent them | ## Colour and theming - **Single-colour** SVGs tint with `colorFilter: ColorFilter.mode(color, BlendMode.srcIn)`, the same technique for both widgets. - **Multi-colour** SVGs can remap colours during `flutter_svg`'s parse with a `ColorMapper` subclass passed as `colorMapper`, for example to swap brand colours in dark mode. - `SvgTheme` supplies `currentColor` for SVGs that use it. ## Measuring before deciding The cost difference matters most where many SVGs appear at once — a grid of pet-breed illustrations, a long list with an SVG badge per row — and on a cold start, when nothing is cached yet. Measure it the way users experience it: 1. Run in **profile mode**; debug parses on the main isolate and exaggerates the cost. 2. Open the screen cold and record a timeline in DevTools, looking for the parse and first-frame work. 3. Compare the same screen with the assets precompiled. If the difference is invisible for a handful of small icons, runtime parsing is acceptable; for dense screens or large illustrations, precompiling usually wins without any code change beyond the loader. ## Pitfalls 1. Expecting a profile trace in debug mode to reflect release: debug parses on the main isolate. 2. Shipping SVGs with filters, then finding they render incompletely; the precompiler would have rejected them. 3. Forgetting that the runtime path never runs the optimisers, so complex illustrations draw more than they need to.
- A large illustrated background SVG makes scrolling janky. Which vector_graphics setting helps, and why?Use the raster strategy: the graphic is drawn once into an image and that image is reused every frame, instead of replaying every path. `VectorGraphic`'s public constructor already uses raster; `SvgPicture` defaults to picture and exposes `renderingStrategy`. The package docs recommend raster for large, complex backdrops at a fixed scale.
- Why might an SVG look correct in a browser but incomplete in Flutter?`vector_graphics` supports groups, paths, shapes, gradients, text, symbols, images and patterns, but not SVG filters and not every text-processing attribute. Running `vector_graphics_compiler` on the file at build time reports unsupported content, which is one more reason to precompile static assets.
Runtime SVG is a recipe cooked each time a diner orders; precompiling is the kitchen preparing the dish before service, so the waiter only plates it. The prepared dish is faster to serve and a bad recipe is caught before anyone orders.
saying these in an interview costs you the question
- flutter_svg and vector_graphics are unrelated rendering engines.
- SvgPicture parses SVGs at build time, so there is no runtime cost.
- flutter_svg always parses in a background isolate, even in debug builds.
- Precompiled vector_graphics files support every SVG feature, including filters.
- Multi-colour SVGs can be shipped as icon-font glyphs without losing colours.