0026 Asset Management Strategy
- Author:
- Catalyst Engineering Team
- Created:
- 2024-01-15
- Status:
- Accepted
- Tags:
-
Context¶
The Catalyst Voices frontend application requires efficient asset management for:
- SVG icons and graphics
- Images (WebP format)
- Fonts
- Videos and animations (Lottie)
- Web asset versioning for cache busting
We need:
- Efficient SVG rendering
- Optimized asset loading
- Cache busting for web deployments
- Type-safe asset access
- Asset compilation pipeline
Decision¶
We use a multi-layered asset management approach:
- SVG Compilation: SVGs compiled to
vector_graphicsbinary format - Asset Generation: Code generation for type-safe asset access via
flutter_gen - Web Asset Versioning: Content-based MD5 hashing for web assets
- WebP Images: WebP format for images (see ADR 0004)
- Asset Organization: Structured asset directories by type
Implementation Details¶
SVG Compilation¶
SVGs are compiled from assets_svg_source/ to assets/ using vector_graphics_compiler:
// compile_svg.dart
final result = encodeSvg(
xml: svgString,
debugName: outputPath,
enableOverdrawOptimizer: false, // Workaround for Flutter issue #174619
);
Workflow:
- Place SVG files in
assets_svg_source/ - Run
dart run compile_svg.dart - Compiled binary files written to
assets/maintaining directory structure
Note: This is a temporary workaround until Flutter issue #158865 is resolved.
Asset Organization¶
assets/
├── images/
│ ├── category/
│ ├── opportunities/
│ └── svg/
├── icons/
├── lottie/
├── videos/
└── fonts/
Type-Safe Asset Access¶
Assets are accessed via generated VoicesAssets class:
import 'package:catalyst_voices_assets/catalyst_voices_assets.dart';
// SVG asset
CatalystSvgPicture.asset(
VoicesAssets.icons.catalystLogo,
)
// Image asset
Image.asset(VoicesAssets.images.category.example)
Web Asset Versioning¶
Web builds use content-based MD5 hashing for cache busting:
Auto-versioned files:
flutter_bootstrap.jsmain.dart.js(and part files)canvaskit/*.wasmandcanvaskit/*.js- WASM-related files (when
--wasmflag is used)
Process:
- Calculate MD5 hash for each file
- Rename file with hash (e.g.,
main.dart.js→main.dart.abc12345.js) - Update all references in HTML and JavaScript
- Generate
asset_versions.jsonmanifest
Asset Preloading¶
Images are precached for better performance:
class GlobalPrecacheImages extends StatelessWidget {
@override
Widget build(BuildContext context) {
// Precache critical images
precacheImage(VoicesAssets.images..., context);
return child;
}
}
Alternatives Considered¶
Direct SVG Rendering (flutter_svg)¶
- Pros: Simple, no compilation step
- Cons: Larger bundle size, slower rendering
- Rejected:
vector_graphicsprovides better performance
Manual Asset References¶
- Pros: No code generation
- Cons: Error-prone, no type safety
- Rejected: Type-safe access prevents errors
No Web Asset Versioning¶
- Pros: Simpler deployment
- Cons: Cache issues, users see stale assets
- Rejected: Cache busting is essential for web
Consequences¶
Positive¶
- Efficient SVG rendering with
vector_graphics - Type-safe asset access
- Automatic cache busting for web
- Organized asset structure
- Optimized asset loading
Negative¶
- SVG compilation step required
- Web asset versioning adds build complexity
- Need to maintain asset organization
Best Practices¶
- Keep SVG source files in
assets_svg_source/ - Run SVG compilation before builds
- Use generated asset classes for access
- Organize assets by type and feature
- Precache critical images
- Version web assets after builds
- Document manual versioning requirements