A microtask and a post-frame callback do not express the same timing requirement. This older experiment scheduled both during initState and logged dependency changes:
@override
void initState() {
super.initState();
print('init');
Future<dynamic>.microtask(() {
print('after init with micro task');
});
SchedulerBinding.instance.addPostFrameCallback((_) {
print('after init with scheduler binding');
});
WidgetsBinding.instance.addPostFrameCallback((_) {
print('after init with widgets binding');
});
}
@override
void didChangeDependencies() {
super.didChangeDependencies();
print('didChangeDependencies');
}
The earlier run recorded:
flutter: init
flutter: didChangeDependencies
flutter: build
flutter: after init with micro task
flutter: after init with scheduler binding
flutter: after init with widgets binding
The trace is an observation from that application. A post-frame callback relates work to a completed frame; it does not prove that every asynchronous initialization task has finished. A microtask is not a general replacement for waiting for layout.
Choose the boundary the operation actually requires, and avoid scheduling the same one-time effect on every rebuild. No lifecycle trace was regenerated for this revision.