-
Notifications
You must be signed in to change notification settings - Fork 846
Open
Description
While analyzing some ANR scenarios, i had this conversation this morning about image caches in flutter.
What's your take on this?
FlyerChatImageMessage seems to make correct assumptions about image size; does it set cacheHeight, too? should it?
Here's what the package actually does:
Display constraints (from the package source):
- BoxConstraints(maxHeight: 300) wraps the whole widget
- Inside: AspectRatio(aspectRatio: message.width / message.height) +
StackFit.expand
- So display is: height ≤ 300px, width = height × aspectRatio
Cache dimensions: the package calls Image(image: _imageProvider, fit:
BoxFit.fill) — no cacheWidth/cacheHeight set anywhere, not even for its own
remote image path. So full-resolution decode happens in all cases.
For customImageProvider: since we pass a raw ImageProvider into Image(image:
..., fit: BoxFit.fill), wrapping it with ResizeImage is the only way to control
decode dimensions.
Should cacheHeight be set too? — Yes. The display height is bounded at 300
(logical px). Given message.width and message.height are available on
ImageMessage, we can compute the actual constrained dimensions precisely:
should we ask for a patch of FlyerChatImageMessage to set cacheHeight?
Yes, it's worth it. Here's the reasoning:
The package already uses LayoutBuilder conditionally (only when topWidget !=
null). A patch would:
1. Make LayoutBuilder unconditional in _buildStack
2. Pass constraints.maxWidth and constraints.maxHeight into Image(image:
_imageProvider, cacheWidth: ..., cacheHeight: ...)
This would benefit all callers — both the default CachedNetworkImageProvider
path and any customImageProvider. The display dimensions are fully determined at
that point (AspectRatio + BoxConstraints(maxHeight: 300)), so constraints in
the LayoutBuilder already reflect the final pixel size.
Without this patch, every image in every chat — including remote ones from the
default path — is decoded at full resolution regardless of the 300px height cap.
That said, ResizeImage on the customImageProvider side still makes sense as a
local workaround in the meantime, since we control that code path. The patch
just fixes the problem more broadly for all image types and all consumers of the
package.
what about using topWidget?
Clever idea, but it doesn't help here. The constraints from LayoutBuilder are
only passed to _buildStack when topWidget != null — but inside _buildStack,
constraints is only used to size the topWidget overlay (line 343), not the Image
itself. The Image(image: _imageProvider, fit: BoxFit.fill) ignores constraints
entirely regardless.
So passing a dummy topWidget would trigger LayoutBuilder but the constraints
would never reach the Image decode call. That's exactly what makes the upstream
patch necessary — the fix has to happen inside _buildStack where the Image is
built.
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels