[vector_graphics] Add precacheVectorGraphic utility function#11716
[vector_graphics] Add precacheVectorGraphic utility function#11716dhananjay6561 wants to merge 3 commits into
Conversation
Adds a top-level precacheVectorGraphic function analogous to precacheImage that warms both the byte-loader cache and the internal _livePictureCache for a given BytesLoader and BuildContext. The context is used to resolve Locale and TextDirection so the computed _PictureKey matches what VectorGraphic will produce at render time, preventing the cache misses that occur when preloading with a null or mismatched context. A reference count of 1 is held in _livePictureCache so the decoded picture survives route transitions where all VectorGraphic widgets temporarily unmount (count would otherwise drop to zero and the picture would be disposed and re-decoded on the next mount). _loadPicture is made static to allow access from the new top-level function while sharing the existing _pendingPictures deduplication map. Fixes flutter/flutter#186481
There was a problem hiding this comment.
Code Review
This pull request introduces the precacheVectorGraphic function to allow warming the vector graphics cache, alongside corresponding unit tests and an export of the new utility. Feedback identifies a potential issue where the function fails to maintain a reference if the graphic is already cached, which could lead to premature eviction during transitions. Additionally, it is recommended to rethrow exceptions when an onError callback is not provided to ensure consistent error handling.
…ror handling - Hold a reference even when the graphic is already live in the cache, using a `precached` flag on `_PictureData` to avoid double-counting on repeated calls for the same key. - Rethrow exceptions when no `onError` callback is provided, matching the behaviour of `precacheImage`. - Add tests for double-precache safety and no-onError rethrow.
|
Hi @ianloic can we have an update on this PR? |
| /// True when [precacheVectorGraphic] holds a reference to this entry. | ||
| /// Prevents double-counting if [precacheVectorGraphic] is called more than | ||
| /// once for the same key. | ||
| bool precached = false; |
There was a problem hiding this comment.
almost certainly want this to be final (or at least read-only)
| ); | ||
|
|
||
| await tester.runAsync(() async { | ||
| await expectLater(precacheFuture, throwsException); |
There was a problem hiding this comment.
when I check out your PR and flutter test test/caching_test.dart to run the tests, the tests which are using _FailingBytesLoader are not passing for me. The test framework is complaining about an exception being thrown.
The tests in vector_graphics_test.dart which use ThrowingBytesLoader use expect(tester.takeException(), isNull);, do we need to do something similar here?
Fixes flutter/flutter#186481
Problem
Developers calling
loader.loadBytes(null)to precache vector graphicsbefore navigating to a route hit two issues:
The
_PictureKeycomputed with a null context uses a default localeand text direction. When
VectorGraphicrenders inside a real widgettree it derives a different key, causing a cache miss and a redundant
decode on the first frame.
_livePictureCacheis reference-counted and evicts pictures whencountreaches zero. Because allVectorGraphicwidgets unmountduring a route transition,
countdrops to zero and the picture isdisposed, forcing a re-decode on the next mount.
Fix
Adds a top-level
precacheVectorGraphic(BytesLoader, BuildContext)function (analogous to Flutter'sprecacheImage) that:LocaleandTextDirectionfrom the suppliedBuildContextso the computed
_PictureKeymatches whatVectorGraphicwill useat render time, eliminating cache misses.
_pendingPicturesdeduplication path (so a concurrent widget load coalesces into the
same future).
_livePictureCachewithcount = 1, keeping the decodedui.Picturealive across route transitions where widgets temporarilyunmount.
_loadPictureis promoted to astaticmethod (its only dependenciesare the static
_pendingPicturesmap and its parameters) so the newtop-level function can share it without duplicating the deduplication
logic.
An
onErrorcallback matches the signature ofVectorGraphicUtilities.loadPictureandprecacheImage.Tests
Three new widget tests in
caching_test.dart:VectorGraphicmountsafter
precacheVectorGraphichas completed.route transition).
onErroris called instead of throwing when the loader fails.