[Prestaties][P2] SVG-afbeeldingen (#2666): elke weergave leest en saneert opnieuw op de UI-isolate, flitst leeg en decodeert ingesloten PNG op 4096 px #2682
Labels
No labels
accepted
bug
declined
docs
duplicate
enhancement
good first issue
in-progress
needs-info
privacy
release-blocker
security
triage
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
LibreKAT/Ocideck#2682
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Symptoom
Sinds de SVG-import (#2666, 30-10) doet elke plek die een SVG-afbeelding toont het hele laadwerk opnieuw bij elke mount. Het gaat om de miniatuur, de editorpreview, de presentator (huidige én volgende dia), de beamer, het zoomvenster en de beeldkiezer. Per mount:
XmlDocument.parse, de allow-list toepassen, opnieuw serialiseren en encoderen — synchroon op de UI-isolate;SvgPicture.string.Tijdens het laden staat er een lege
SizedBox. Bij een diawissel in presentator en beamer, bij scrollen door de dialijst en na elke editor-remount (undo/redo zet de editor op een nieuwe revisie) flitst het beeld dus weg.Een SVG die alleen een PNG insluit (dat doen veel exporttools) wordt bij elke mount opnieuw op maximaal 4096 px gedecodeerd, langs de ImageCache heen.
Oorzaak
lib/widgets/safe_svg_image.dart:84-118:_load()hoort bij de State; tussen instanties is er geen cache.sanitizeImportedSvgBytes(lib/utils/sanitize_svg.dart:27-43, metXmlDocument.parseop r. 73) is synchroon.ConnectionState != donevolgt een legeSizedBox. De rasterroute gebruikt juistgaplessPlayback: true, omdat een leeg frame tussen dia's "fataal is bij video-opname" (lib/widgets/slides/previews/media_previews_image.dart:294-297).cappedMemoryImage(png)krijgt bij elke lading een nieuwUint8List. De identiteitssleutel mist daardoor altijd, terwijl de documentatie vancappedMemoryImage(lib/utils/image_limits.dart:379-381) juist om hetzelfde object vraagt. ZondermaxEdgeis er bovendien geen maat-decode, zoals #2625 die voor foto's invoerde.*Sync(-aanroepen, geen zwaar parsen.Voorgestelde oplossing
_SafeSvgData(de gesaneerde string plus het ingesloten-PNG-object) bewaart. Sleutel: (pad, mtime, grootte), of de bytes-identiteit bijmem:. Begrens hem in bytes (bijv. 32 MiB totaal). Dit is hetzelfde patroon als de contrast-memo (averageImageColor).Isolate.run). Kleinere SVG's mogen synchroon blijven._SafeSvgDatain de State), en lever een cache-hit synchroon af viaSynchronousFuture. Dan is er geen leeg frame meer.ResolvedDecodeImagelopen, metcappedMemoryImage(png, maxEdge: plan.edge)en het gecacheteUint8List. Dan werken de ImageCache en de maat-trede van #2625 weer.Wat overeind moet blijven
containedRealPathOrNull); een ontsnapping geeft de outsideDeck-placeholder.errorBuilder.Toets
SafeSvgImage.fileop hetzelfde pad saneren samen één keer (teller-naad).SizedBox.Gevonden bij codelezing tijdens de vervolginspectie van 31-10-2026. Deze code landde ná de prestatieronde van 29-10.
Opgepakt. Tak: fix/vervolginspectie-3110. Verwachte reikwijdte: de bestanden die in de oorzaak van dit issue staan, plus een regressietest.
Opgepakt. Tak: fix/vervolginspectie-3110. Verwachte reikwijdte: lib/widgets/safe_svg_image.dart, lib/utils/sanitize_svg.dart, lib/utils/image_limits.dart.
Staat op main in
a6b4dc066(9bad356e5). Een geïmporteerde SVG wordt één keer opgeschoond en blijft staan bij een diawissel. Saneertijden van 100 KiB, 1 MiB en 10 MiB zijn niet gemeten.Opgelost op main in
a6b4dc066. De zin „elke mount leest en saneert opnieuw en flitst leeg“ is gedekt door de procescache en het blijven staan van het vorige beeld in lib/widgets/safe_svg_image.dart. Niet meegenomen: de saneertijden van 100 KiB, 1 MiB en 10 MiB zijn niet gemeten.