[Prestaties][P2] Groot deck openen: koude kwaliteits- en privacyanalyse blokkeert de UI (655 + 450 ms bij 600 dia's) #2634

Closed
opened 2026-10-28 16:31:51 +00:00 by brenno · 0 comments
Owner

Symptoom

Een grote presentatie openen bevriest de app kort voordat je kunt werken; hoe groter het deck, hoe langer.

Oorzaak

Bij het openen draaien de kwaliteitscontrole en de tekst-privacyscan koud en synchroon op de UI-isolate (de memo's zijn per dia en dus nog leeg). Daarnaast wordt het bestand tweemaal gelezen en tweemaal op uitvoerbare inhoud gescand: eerst voor het alarm (scanForUnsafeMarkdown, lib/state/tabs_provider.dart:484 → file_service.dart:646), daarna opnieuw in openDeckDetailed vlak vóór het parsen (lib/services/file/file_service_open.dart:296). Die tweede keer is bewust (TOCTOU), de eerste is dan overbodig.

Meting

Tijdelijke meetproef (debug-JIT, Apple Silicon), gangbare mix van diatypes:

Dia's Kwaliteit koud Privacy koud Parsen
150 236 ms 143 ms 5 ms
600 655 ms 450 ms 16 ms

Parsen en serialiseren zijn verwaarloosbaar (ook de autosave elke 25 s is dat: 0,5-1,8 ms). De analyse is het werk.

Voorgestelde oplossing

  1. Tekst-privacyscan is pure Dart: koud in Isolate.run over alle dia's, resultaten terug in de per-dia-memo.
  2. Kwaliteitscontrole meet met TextPainter en hoort op de UI-isolate; verdeel de koude pas over frames (bijv. 20 dia's per idle-taak via SchedulerBinding.scheduleTask(…, Priority.idle)), en laat het paneel/de badges oplopen terwijl hij loopt. De export-gate wacht op "compleet".
  3. Het alarm uit dezelfde scan halen als het parsen (één lees- en scanbeurt; bij bevindingen het alarm vanuit openDeckDetailed laten opgaan).

Wat overeind moet blijven

Fail-closed: niets uitvoerbaars wordt geopend; de export weigert zolang de analyse niet compleet is.

Toets

Open een deck van 600 dia's in een widgettest: geen enkele frame-taak > 50 ms (via SchedulerBinding.addTimingsCallback in een integratietest), uitkomst identiek aan de synchrone analyse.

Onderdeel van de prestatie- en stabiliteitsinspectie van 28-10-2026 (EPIC #2637).

## Symptoom Een grote presentatie openen bevriest de app kort voordat je kunt werken; hoe groter het deck, hoe langer. ## Oorzaak Bij het openen draaien de kwaliteitscontrole en de tekst-privacyscan **koud** en synchroon op de UI-isolate (de memo's zijn per dia en dus nog leeg). Daarnaast wordt het bestand tweemaal gelezen en tweemaal op uitvoerbare inhoud gescand: eerst voor het alarm (`scanForUnsafeMarkdown`, `lib/state/tabs_provider.dart:484` → `file_service.dart:646`), daarna opnieuw in `openDeckDetailed` vlak vóór het parsen (`lib/services/file/file_service_open.dart:296`). Die tweede keer is bewust (TOCTOU), de eerste is dan overbodig. ## Meting Tijdelijke meetproef (debug-JIT, Apple Silicon), gangbare mix van diatypes: | Dia's | Kwaliteit koud | Privacy koud | Parsen | |---|---|---|---| | 150 | 236 ms | 143 ms | 5 ms | | 600 | 655 ms | 450 ms | 16 ms | Parsen en serialiseren zijn verwaarloosbaar (ook de autosave elke 25 s is dat: 0,5-1,8 ms). De analyse is het werk. ## Voorgestelde oplossing 1. **Tekst-privacyscan** is pure Dart: koud in `Isolate.run` over alle dia's, resultaten terug in de per-dia-memo. 2. **Kwaliteitscontrole** meet met `TextPainter` en hoort op de UI-isolate; verdeel de koude pas over frames (bijv. 20 dia's per idle-taak via `SchedulerBinding.scheduleTask(…, Priority.idle)`), en laat het paneel/de badges oplopen terwijl hij loopt. De export-gate wacht op "compleet". 3. Het alarm uit dezelfde scan halen als het parsen (één lees- en scanbeurt; bij bevindingen het alarm vanuit `openDeckDetailed` laten opgaan). ## Wat overeind moet blijven Fail-closed: niets uitvoerbaars wordt geopend; de export weigert zolang de analyse niet compleet is. ## Toets Open een deck van 600 dia's in een widgettest: geen enkele frame-taak > 50 ms (via `SchedulerBinding.addTimingsCallback` in een integratietest), uitkomst identiek aan de synchrone analyse. Onderdeel van de prestatie- en stabiliteitsinspectie van 28-10-2026 (EPIC #2637).
brenno 2026-10-29 12:20:21 +00:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
LibreKAT/Ocideck#2634
No description provided.