Repository navigation
fix: Avoid decoding static images again when a listener is re-added - #1062
Conversation
rickdijk
left a comment
There was a problem hiding this comment.
One more, outside the diff, at line 155 of multi_image_stream_completer.dart: if the last listener leaves while the first static decode is running, the decoded frame lands in _nextFrame and is dropped without being emitted. _framesEmitted stays 0, so the next addListener decodes again. On Firefox and Safari that is the blank-image path from the PR description, so navigating away mid-load and back can still blank the image. Calling setImage with the frame even when nobody is listening (it handles an empty listener list) would keep it for the next listener.
|
Once all comments are resolved, I'd like to ask you to bump the version of the package and update CHANGELOG.md too. |
|
Thank you for your clarification, I will work on resolving it asap and dig deep in how it handles the multi frame images |
|
@rickdijk I have resolved the different states of listeners adding / removing and re-addition in static, animated decoding states along with tests covering the 5 cases, if anything is still needed, let me know :)) |
rickdijk
left a comment
There was a problem hiding this comment.
Thanks for picking this up. The static-image fix looks right; the comments below are mostly about edge cases around it.
Two things on the description:
- It says
_framesEmittedis used, but the code adds_currentCodecHasImage. - The template checklist item reads "Rebased onto current
develop". Please leave it as is rather than rewording it tomain. Per AGENTS.md it is read asmain, but the template text itself isn't edited in an unrelated PR.
One behaviour note, not introduced here: a finite animation that has finished restarts when a listener is re-added, because frameCount > 1 triggers a fresh decode. That matches the framework's condition, so I'm fine leaving it for #949.
Thank you for your patience with my PR, I have applied the changes requested, let me know if anything still needs any work. |
✨ What kind of change does this PR introduce? (Bug fix, feature, docs update...)
Bug fix
When an image stream loses all its listeners and gets one back,
MultiImageStreamCompleter.addListenerasks the codec for a new frame, even for a static image that was already decoded. This happens every time a route is covered and uncovered, becauseImagestops listening whileTickerModeis off.On native this is only wasted work. On web, in Firefox and Safari (where Flutter does not use the browser
ImageDecoder), the second decode comes back blank, so images on a screen turn into empty boxes after navigating to another route and back.🆕 What is the new behavior (if this is a feature change)?
MultiFrameImageStreamCompleter.addListeneruses, but_currentImageis private in the framework so I used_framesEmittedinstead, and it is now reset every time a new codec arrives.setImageinstead of being dropped, so the next listener gets it without decoding again. The trade-off is that a completer kept alive only by theImageCachekeeps this decoded image even if it's never shown. It's the same memory an image that was already shown keeps.💥 Does this PR introduce a breaking change?
No
🐛 Recommendations for testing
flutter test: the new test fails onmain(numFramesAskedis 2) and passes with this change.CachedNetworkImages in Firefox or Safari, push another route, pop back. Images stay visible with this change and go blank without it.📝 Links to relevant issues/docs
Related: #949 replaces this completer with the framework one, which would also fix this. This PR is the minimal fix in the meantime.
🤔 Checklist before submitting