flutter-pre-caching
Use when preloading fonts, asset/network images, Lottie/Rive animations, local JSON/config, warming initial API data, or optimizing Flutter Web startup.
Install / Use
npx skills add evanca/flutter-ai-rules --skill flutter-pre-cachingInstalls into whichever agent you are using.
SKILL.md
Installable skill definition
Quality Score
Category
Development & EngineeringSupported Platforms
Our assessment of flutter-pre-caching
flutter-pre-caching scores 92/100 on our quality scale, 888th of 4,634 Development & Engineering skills we index (top 20%).
Its SKILL.md is 18 KB long, well organised into 31 sections with 42 code examples: a thorough specification that gives an agent plenty to work with.
It has 646 GitHub stars, a meaningful sign that others use it.
Maintenance, license and trust
- The repository was last updated 19 days ago, so flutter-pre-caching is actively maintained.
- It is released under the MIT license, a permissive license that allows use, modification and commercial use with attribution.
- Its trust signals score 100/100, with no cautions. These come from repository metadata, not a code audit — read the skill file before letting an agent act on it.
flutter-pre-caching compared with similar skills
All 4 of these similar skills score higher than flutter-pre-caching; compare them before choosing.
| Skill | Score | Stars | Updated | Format |
|---|---|---|---|---|
| flutter-pre-caching (this skill)by evanca | 92 | 646 | 19d ago | SKILL.md |
| Agent-Reachby Panniantong | 100 | 89.8k | 18d ago | CLAUDE.md |
| headroomby headroomlabs-ai | 100 | 74.4k | today | CLAUDE.md |
| ai-job-searchby MadsLorentzen | 100 | 44.9k | today | CLAUDE.md |
| claude-howtoby luongnv89 | 100 | 41.7k | 3d ago | CLAUDE.md |
Frequently asked questions
- How do I install flutter-pre-caching?
- Run
npx skills add evanca/flutter-ai-rules --skill flutter-pre-caching. The install tabs above show the steps for each supported agent. - Which AI agents does flutter-pre-caching work with?
- It is written for Universal, as a SKILL.md file. Other agents that read the same format can often use it too.
- Is flutter-pre-caching safe to use?
- It is MIT-licensed and scores 100/100 on trust signals. Skills are instructions an agent will follow, so read the file before installing it and do not approve commands you do not understand.
- Is flutter-pre-caching still maintained?
- The repository was last updated 19 days ago, so flutter-pre-caching is actively maintained.
Skill content
View source on GitHubname: flutter-pre-caching description: "Use when preloading fonts, asset/network images, Lottie/Rive animations, local JSON/config, warming initial API data, or optimizing Flutter Web startup." license: MIT
Pre-caching in Flutter and Flutter Web
Pre-caching helps avoid jank, loading flashes, font swaps, and delayed first renders.
The key rule:
Pre-cache only what the user will likely see in the next 1 to 2 screens.
Do not pre-cache the whole app. That can slow startup and waste memory.
1. Google Fonts
Runtime Google Fonts preloading
Use GoogleFonts.pendingFonts() to load the font variants before showing text.
import 'package:flutter/material.dart';
import 'package:google_fonts/google_fonts.dart';
class ExampleSimple extends StatefulWidget {
const ExampleSimple({super.key});
@override
State<ExampleSimple> createState() => _ExampleSimpleState();
}
class _ExampleSimpleState extends State<ExampleSimple> {
late final Future<List<void>> googleFontsPending;
@override
void initState() {
super.initState();
googleFontsPending = GoogleFonts.pendingFonts([
GoogleFonts.poppins(),
GoogleFonts.montserrat(fontStyle: FontStyle.italic),
]);
}
@override
Widget build(BuildContext context) {
final pushButtonTextStyle = GoogleFonts.poppins(
textStyle: Theme.of(context).textTheme.headlineMedium,
);
final counterTextStyle = GoogleFonts.montserrat(
fontStyle: FontStyle.italic,
textStyle: Theme.of(context).textTheme.displayLarge,
);
return FutureBuilder<List<void>>(
future: googleFontsPending,
builder: (context, snapshot) {
if (snapshot.connectionState != ConnectionState.done) {
return const SizedBox();
}
return Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
'You have pushed the button this many times:',
style: pushButtonTextStyle,
),
Text(
'0',
style: counterTextStyle,
),
],
);
},
);
}
}
Production recommendation
For production and offline support, prefer bundling critical fonts as assets.
flutter:
fonts:
- family: AppFont
fonts:
- asset: assets/fonts/AppFont-Regular.ttf
- asset: assets/fonts/AppFont-Bold.ttf
weight: 700
Use it in the app theme:
MaterialApp(
theme: ThemeData(
fontFamily: 'AppFont',
),
)
2. Asset images
Use precacheImage for images that appear soon.
@override
void didChangeDependencies() {
super.didChangeDependencies();
precacheImage(
const AssetImage('assets/images/header.png'),
context,
);
}
Then use the image normally:
Image.asset('assets/images/header.png')
3. Network images
Use precacheImage with NetworkImage.
@override
void didChangeDependencies() {
super.didChangeDependencies();
precacheImage(
const NetworkImage('https://example.com/image.png'),
context,
);
}
Then use it normally:
Image.network('https://example.com/image.png')
Important:
precacheImage warms Flutter’s in-memory image cache. It does not provide long-term offline caching.
For disk caching, use a package like cached_network_image:
dependencies:
cached_network_image: ^latest
Example:
CachedNetworkImage(
imageUrl: 'https://example.com/image.png',
)
4. Multiple image preloading
@override
void didChangeDependencies() {
super.didChangeDependencies();
final images = <ImageProvider>[
const AssetImage('assets/images/header.png'),
const AssetImage('assets/images/avatar.png'),
const NetworkImage('https://example.com/banner.png'),
];
for (final image in images) {
precacheImage(image, context);
}
}
5. Waiting until images are ready
precacheImage returns a Future<void>, so you can wait before rendering the real UI.
late Future<void> _preloadImagesFuture;
@override
void didChangeDependencies() {
super.didChangeDependencies();
_preloadImagesFuture = Future.wait([
precacheImage(
const AssetImage('assets/images/header.png'),
context,
),
precacheImage(
const NetworkImage('https://example.com/banner.png'),
context,
),
]);
}
@override
Widget build(BuildContext context) {
return FutureBuilder<void>(
future: _preloadImagesFuture,
builder: (context, snapshot) {
if (snapshot.connectionState != ConnectionState.done) {
return const CircularProgressIndicator();
}
return Column(
children: [
Image.asset('assets/images/header.png'),
Image.network('https://example.com/banner.png'),
],
);
},
);
}
[!NOTE] Use
didChangeDependencies, notinitState, when you needcontextforprecacheImage.
6. What should normally be pre-cached on app start?
Good candidates:
- App logo
- First screen hero image
- First visible background image
- Current user avatar
- First visible card/list images
- Main font variants
- Small local config files
- Translations needed for first paint
- First API request
- Lottie/Rive animation shown immediately
Bad candidates:
- All product images
- All gallery images
- All remote feed images
- All icons in the app
- All route images
- Every image from every screen
- Large animations not shown immediately
7. Practical app-start preloader
class AppPreloader {
const AppPreloader();
Future<void> preload(BuildContext context) async {
await Future.wait([
_precacheImages(context),
_loadCriticalAssets(),
_warmUpInitialData(),
]);
}
Future<void> _precacheImages(BuildContext context) {
return Future.wait([
precacheImage(
const AssetImage('assets/images/home_hero.png'),
context,
),
precacheImage(
const AssetImage('assets/images/logo.png'),
context,
),
]);
}
Future<void> _loadCriticalAssets() async {
await rootBundle.loadString('assets/config/app_config.json');
}
Future<void> _warmUpInitialData() async {
// Example:
// await userRepository.getCurrentUser();
}
}
Usage:
late Future<void> _preloadFuture;
@override
void didChangeDependencies() {
super.didChangeDependencies();
_preloadFuture = const AppPreloader().preload(context);
}
With FutureBuilder:
@override
Widget build(BuildContext context) {
return FutureBuilder<void>(
future: _preloadFuture,
builder: (context, snapshot) {
if (snapshot.connectionState != ConnectionState.done) {
return const SplashScreen();
}
return const HomeScreen();
},
);
}
8. Local JSON / config preloading
Useful for feature flags, local app config, mock data, translations, or onboarding content.
import 'package:flutter/services.dart';
final configJson = await rootBundle.loadString(
'assets/config/app_config.json',
);
Example:
class AppConfigLoader {
Future<String> load() {
return rootBundle.loadString('assets/config/app_config.json');
}
}
9. Initial API request warm-up
This is not pre-caching in the Flutter image-cache sense, but it is often the most useful startup optimization.
final userFuture = userRepository.getCurrentUser();
final dashboardFuture = dashboardRepository.getDashboard();
Example:
class StartupData {
const StartupData({
required this.user,
required this.dashboard,
});
final User user;
final Dashboard dashboard;
}
Future<StartupData> loadStartupData() async {
final results = await Future.wait([
userRepository.getCurrentUser(),
dashboardRepository.getDashboard(),
]);
return StartupData(
user: results[0] as User,
dashboard: results[1] as Dashboard,
);
}
10. Lottie preloading
If the animation appears immediately, preload it.
final composition = await AssetLottie(
'assets/animations/success.json',
).load();
Use this only for animations shown early. Avoid preloading many large animations on app start.
11. Rive preloading
Rather than triggering the asset load during a build (which causes jank), preload the RiveFile byte data in advance:
import 'package:flutter/services.dart';
import 'package:rive/rive.dart';
// Preload the RiveFile
final data = await rootBundle.load('assets/animations/character.riv');
final riveFile = RiveFile.import(data);
// Display using direct constructor to avoid initialization delays:
RiveAnimation.direct(riveFile);
This ensures that the animation renders immediately upon widget mount.
12. Shader warm-up
Most apps do not need this. It can help if you have:
- Heavy custom painting
- Complex transitions
- Known animation jank
- Older rendering paths
Basic shape:
class CustomShaderWarmUp extends ShaderWarmUp {
@override
void warmUpOnCanvas(Canvas canvas) {
final paint = Paint();
canvas.drawRect(
const Rect.fromLTWH(0, 0, 100, 100),
paint,
);
}
}
Then set it before runApp:
void main() {
PaintingBinding.instance.shaderWarmUp = CustomShaderWarmUp();
runApp(const MyApp());
}
Use this only when profiling shows shader compilation jank.
13. Flutter Web: different mindset
On Flutter Web, think less:
- Pre-cache everything in memory
Think more:
- Make the browser download key files early
- Warm Flutter cache only for first-screen assets
- Avoid surprise font fallback downloads
- Avoid loading huge assets before first paint
14. Flutter Web image preload
For critical first-screen images, use both browser preload and Flutter precacheImage.
In web/index.html:
<link
rel="preload"
href="assets/assets/images/home_hero.png"
as="image"
>
In Flutter:
await precacheImage(
const AssetImage('assets/images/home_hero.png'),
context,
);
Why both?
- HTML preload starts the browser download earlier.
precacheImagewarms Flutter's image cache.
15. Flutter Web network image preload
In web/index.html:
<link
rel="preload"
href="https://example.com/banner.png"
as="image"
>
In Flutter:
await precacheImage(
const NetworkImage('https://example.com/banner.png'),
context,
);
Only do this for images the user is almost guaranteed to see.
16. Flutter Web font preload
Declare the font in pubspec.yaml:
flutter:
fonts:
- family: AppFont
fonts:
- asset: assets/fonts/AppFont-Regular.ttf
- asset: assets/fonts/AppFont-Bold.ttf
weight: 700
Preload the critical font in web/index.html:
<link
rel="preload"
href="assets/assets/fonts/AppFont-Regular.ttf"
as="font"
type="font/ttf"
crossorigin
>
Use it in Flutter:
ThemeData(
fontFamily: 'AppFont',
)
Usually preload:
- Regular
- Bold
- Maybe medium
Avoid preloading every weight and italic variant unless the first screen needs them.
17. Flutter Web and emojis
Emojis can trigger font fallback work.
Example:
Text('Welcome 👋 🎉')
On web, this can cause:
- Extra font download
- Delayed render
- Fallback font swap
- Blank boxes
- Different emoji style across platforms
18. Option 1: avoid emojis on first paint
Simple and effective:
Text('Welcome')
Then show emojis after the app has loaded:
Text('Welcome 👋')
This is often the best option if emojis are decorative.
19. Option 2: bundle and preload an emoji font
Add the font to pubspec.yaml:
flutter:
fonts:
- family: NotoColorEmoji
fonts:
- asset: assets/fonts/NotoColorEmoji.ttf
Preload it in web/index.html:
<link
rel
Truncated for display — read the full file on GitHub.
Related Skills
Agent-Reach
89.8kGive your AI agent eyes to see the entire internet. Read & search Twitter, Reddit, YouTube, GitHub, Bilibili, XiaoHongShu — one CLI, zero API fees.
headroom
74.4kCompress tool outputs, logs, files, and RAG chunks before they reach the LLM. 20% fewer tokens for coding agents, 60-95% fewer tokens for JSON, same answers. Library, proxy, MCP server.
ai-job-search
44.9kThe job search that runs on your machine. AI job application framework built on Claude Code: evaluate postings, tailor CVs, write cover letters, prep interviews. Fork it and own it.
claude-howto
41.7kA visual, example-driven guide to Claude Code — from basic concepts to advanced agents, with copy-paste templates that bring immediate value.
Languages
Trust signals
From repository metadata: license, adoption, age and documentation. Not a code audit — see the Safety scan above for what the skill file itself contains.
