Skip to content

Instantly share code, notes, and snippets.

@s0nerik
Created March 20, 2025 23:53
Show Gist options
  • Save s0nerik/bf694393f6c91f7cdb33b269e1f6a521 to your computer and use it in GitHub Desktop.
Save s0nerik/bf694393f6c91f7cdb33b269e1f6a521 to your computer and use it in GitHub Desktop.
Flutter widget rebuilds: const vs cached instance vs no caching
import 'package:flutter/material.dart';
import 'package:flutter/scheduler.dart';
void main() => runApp(const MyApp());
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
debugShowCheckedModeBanner: false,
home: const HomePage(),
);
}
}
class HomePage extends StatefulWidget {
const HomePage({super.key});
@override
State<HomePage> createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
int _counter = 0;
bool _useConstChild = false;
bool _useCachedChild = false;
late Widget _cachedChild;
void initState() {
super.initState();
_cachedChild = Counter(counter: 0);
}
void _incrementCounter() {
setState(() {
_counter += 1;
_cachedChild = Counter(counter: _counter);
});
}
void _rebuild() {
setState(() {});
}
@override
Widget build(BuildContext context) {
final widgetCachingType =
_useConstChild
? 'const'
: _useCachedChild
? 'cached instance'
: 'none';
return Scaffold(
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
spacing: 16,
children: [
if (_useConstChild)
const Counter(counter: -1)
else if (_useCachedChild)
_cachedChild
else
Counter(counter: _counter),
FilledButton(
onPressed: _incrementCounter,
child: Text('Increment'),
),
FilledButton(
onPressed: _rebuild,
child: Text('Rebuild the HomePage'),
),
FilledButton(
onPressed:
() => setState(() {
_useConstChild = true;
_useCachedChild = false;
}),
child: Text('Use const child'),
),
FilledButton(
onPressed:
() => setState(() {
_useConstChild = false;
_useCachedChild = true;
}),
child: Text('Use cached child'),
),
FilledButton(
onPressed:
() => setState(() {
_useConstChild = false;
_useCachedChild = false;
}),
child: Text('Don\'t use any widget caching'),
),
Text('Widget caching: ${widgetCachingType}'),
],
),
),
);
}
}
class Counter extends StatelessWidget {
const Counter({super.key, required this.counter});
final int counter;
@override
Widget build(BuildContext context) {
SchedulerBinding.instance.addPostFrameCallback((_) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text("Counter rebuilt with value: $counter"),
duration: Duration(seconds: 1),
),
);
});
return Text('$counter', style: Theme.of(context).textTheme.headlineMedium);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment