0873fa42bb
Test Suite / test (24.15.0) (push) Has been cancelled
- Introduced a new function `_shellBranchIndexForPath` to determine the index of the shell branch based on the path. - Replaced `ShellRoute` with `StatefulShellRoute.indexedStack` for better state management during navigation. - Updated `AppShell` to handle navigation path changes and integrate with the new routing structure. - Organized routes into `StatefulShellBranch` for better modularity and clarity. - Enhanced admin panel functionality with improved alias management and UI updates. - Added new methods in `ReceiptImportSessionNotifier` for managing selected items and edits more efficiently. - Improved UI components in receipt import and admin panels for better performance and user experience. - Added PageStorageKeys to various ListViews to maintain scroll positions across navigation. - Documented performance goals and profiling strategies in a new PERFORMANCE.md file.
4.4 KiB
4.4 KiB
Flutter Performance – Profileringsguide
Mål
| Mätpunkt | Gränsvärde |
|---|---|
| Frame build-tid (60 Hz) | < 16 ms |
| Frame build-tid (120 Hz) | < 8 ms |
| Scroll jank (tappade frames) | 0 vid normal scroll |
| Minnesfotavtryck (app) | < 200 MB |
1. Starta i profile-läge
Kör alltid profilmätningar i profile mode, inte debug. Debug-läget har JIT-kompilering och extra overhead.
# Mot fysisk enhet
flutter run --profile
# Mot Chrome (web)
flutter run -d chrome --profile
2. Flutter DevTools – Öppna
flutter pub global activate devtools
flutter pub global run devtools
Eller anslut direkt från terminalen när appen körs i profile mode – Flutter skriver ut en DevTools-URL.
3. Timeline – Mät frame-tider
- Öppna Performance-fliken i DevTools.
- Klicka Record.
- Utför den aktion du vill mäta (t.ex. byt vy, scrolla).
- Klicka Stop.
- Granska:
- UI thread (Dart-kod) – bör vara < 16 ms per frame.
- Raster thread (GPU) – bör vara < 16 ms per frame.
- Röda/gula staplar = jank.
Kritiska mätpunkter i appen
| Scenario | Vad att leta efter |
|---|---|
| Byta vy (NavigationBar) | Frame-tid vid StatefulShellRoute-byte; bör vara < 32 ms totalt |
| Scrolla receptlista | Inga röda frames; GridView.builder bör recykla element |
| Scrolla adminpaneler | ListView.builder i embedded-läge; verifiera att ingen NeverScrollableScrollPhysics blockerar |
| Kvittoimport – kryssa i rad | Endast den berörda raden bör rebuilda (ConsumerWidget.select) |
| Kvittoimport – "Välj alla" | Batch-uppdatering via setSelectedForAll – en enda state = |
4. Widget Rebuild-spårning
Aktivera rebuild-räknare i DevTools under Inspector → Widget rebuild counts.
Alternativt: lägg till tillfällig räknare i en widget:
int _buildCount = 0;
@override
Widget build(BuildContext context, WidgetRef ref) {
debugPrint('${widget.runtimeType} build #${++_buildCount}');
// ...
}
Förväntade rebuild-mönster efter optimeringar
_ReceiptImportResultRowmed index X ska bara rebuilda närselected[X]ändras, inte när andra rader kryssas.AppShellska inte rebuilda vid vy-byte (StatefulShellRoute bevarar grenar).- Admin-paneler ska inte rebuilda hela listan vid en alias-ändring.
5. Memory Profiler
- DevTools → Memory-fliken.
- Klicka Take snapshot före och efter en tung operation.
- Jämför levande objekt – leta efter läckor (ackumulerade
StreamSubscription,Timer,Notifier).
6. flutter analyze + dart fix
flutter analyze
dart fix --apply
Åtgärda alla varningar om const och onödiga rebuilds.
7. Identifierade optimeringar (genomförda)
| Område | Åtgärd | Effekt |
|---|---|---|
| Admin-paneler | Tog bort NeverScrollableScrollPhysics + shrinkWrap |
Scroll fungerar, O(n) layout istället för O(n²) |
| Admin alias-lista | ListView.builder istället för spread |
Virtualiserad lista |
| FABs | Explicita heroTag på alla FABs |
Eliminerar hero-animation-krasch vid vy-byte |
| Scrollables | PageStorageKey på alla listvy |
Scrollposition bevaras vid vy-byte |
| Router | StatefulShellRoute.indexedStack |
Branch-state bevaras; ingen ombyggnad vid tab-byte |
| Kvittoimport – resultatlista | ListView.builder + SizedBox bound height |
Virtualiserad; max 620 px synlig |
| Kvittoimport – radwidget | ConsumerWidget med provider.select((s) => s?.selected[index]) |
Endast ändrad rad rebuildar vid checkbox-toggle |
| Kvittoimport – batch-API | setSelectedForAll, setSelectedForIndexes, setImportedResult |
En state = och en SharedPreferences-skrivning per operation |
8. Snabbtest – Verifiera förbättringar
# Kör i profile mode och öppna DevTools automatiskt
flutter run --profile --devtools-server-address=http://127.0.0.1:9100
Kontrollchecklista:
- Vy-byte NavigationBar: inga röda frames i Timeline
- Scroll i receptlista: < 2 tappade frames per 100 frames
- Scroll i admin-flikar: fungerar utan lock
- Kvittoimport – checkbox-toggle: rebuild-räknare ökar bara för berörd rad
- Kvittoimport – "Välj alla": en burst av rebuilds (en per rad), inga dubbla