State and performance
- Flutter course
- Intermediate
- Lesson 4/99
- 4 min
Learn setState's cost and what it rebuilds.
The cost of setState
Every setState call rebuilds the subtree of that widget. That is, the build method runs again and the widget tree is recreated.
setState(() { _count++; });
// only this widget's subtree
// is rebuiltParent widgets are not affected.
Rebuild scope
setState rebuilds only the widget owned by that State; the build methods of parent widgets are not called. So in large widget trees, keeping state as low as possible improves performance.
class Big extends StatelessWidget {
Widget build(BuildContext context) {
// Big is not rebuilt
return Small();
}
}If you keep state in a small subtree, rebuild cost stays low.
Practice Parent stateless, child stateful counter
Make Ebeveyn a stateless widget. The Sayac stateful widget holds _sayac and in initState calls print('Sayac oluşturuldu'). When the button is pressed, increment _sayac with setState.
Starter code
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(home: Ebeveyn());
}
}
class Ebeveyn extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(child: Sayac()),
);
}
}
class Sayac extends StatefulWidget {
@override
_SayacState createState() => _SayacState();
}
class _SayacState extends State<Sayac> {
int _sayac = 0;
@override
void initState() {
super.initState();
print('Sayac oluşturuldu');
}
@override
Widget build(BuildContext context) {
return Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text('$_sayac'),
ElevatedButton(
// setState ile _sayac'ı artır
onPressed: () {},
child: Text('Artır'),
),
],
);
}
}Sample solution
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(home: Ebeveyn());
}
}
class Ebeveyn extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(child: Sayac()),
);
}
}
class Sayac extends StatefulWidget {
@override
_SayacState createState() => _SayacState();
}
class _SayacState extends State<Sayac> {
int _sayac = 0;
@override
void initState() {
super.initState();
print('Sayac oluşturuldu');
}
@override
Widget build(BuildContext context) {
return Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text('$_sayac'),
ElevatedButton(
onPressed: () {
setState(() {
_sayac++;
});
},
child: Text('Artır'),
),
],
);
}
}Expected output
Sayac oluşturuldu
Questions and answers
Review the lesson questions together with their answers. To test yourself, solve the lesson interactively.
1 What is rebuilt when setState is called?
- setState rebuilds the entire app
- setState rebuilds the parent but not the children
- setState rebuilds only the subtree of that State Correct answer
- setState does not rebuild anything
Explanation: setState rebuilds only the widget owned by that State and its subtree; parents' build methods are not called.
2 Which method runs after setState
class _MyState extends State<MyWidget> {
int x = 0;
@override
Widget ____(BuildContext context) {
return Text('$x');
}
}
class _MyState extends State<MyWidget> {
int x = 0;
@override
Widget build(BuildContext context) {
return Text('$x');
}
}
Explanation: setState marks the State dirty and on the next frame the build method is called again; the parent's build is not called.
3 Rebuild and performance parts
| Term | Meaning |
|---|---|
setState |
Rebuilds only that State's subtree |
Subtree |
A widget and all its descendants |
Büyük ağaçta state aşağıda |
Reduces rebuild cost |
Ebeveyn widget |
Unaffected by setState |