Is it normal for `Image` to be never skipped? ```...
# compose
u
Is it normal for
Image
to be never skipped?
Copy code
Image(
    modifier = Modifier
        .size(48.dp)
        .padding(12.dp),
    painter = painterResource(id = R.drawable.ic_headphones),
    contentDescription = null,
)
I’m looking around in Layout monitor and I see this never skipped when ui is recomposed
m
It's unclear to me based on looking at the source code if painterResource is re-evaluated every time. Perhaps use a remember on the resulting resource and see if it's still skipped or not. val imagePainter = remember { painterResource(...) }
e
How about
rememberPainterResource()
instead of
painterResource()
?
m
Where do you see rememberPainterResource in the API? There's a rememberVectorPainter (which is used internally in painterResource), but i don't see anything beyond that.
e
Ah sorry, I seem to have misread.
z
Is your drawable a bitmap or vector? Looking at the impl of
painterResource
, if it’s a bitmap, I’m guessing this might be because it remembers the bitmap but creates a new
BitmapPainter
every time, which implements
equals
but isn’t marked as
@Stable
and contains a non-stable
ImageBitmap
field so probably isn’t inferred as stable either.
u
vector
z
hm not sure then
u
can you simulate it as well or is it a me thing?
z
(i filed the bitmap bug to follow up on)
in the middle of something, will try to repro in a bit
k
FWIW, I noticed this with the jetflix demo app as well when you scroll a carousel horizontally. Surprising number of compose counts only for images loaded with Coil.
a
Since
Painter
is not a stable class, it seems expected that
Image
is not skippable.
u
so a oversight/bug?
a
Working as intended, I think, as not all subclasses of
Painter
are guaranteed to be stable.
u
But im pretty sure imageview equivalent is idempotent
a
Unskippable doesn't mean non-idempotent.
u
how so, if arguments are equal, then it is skipped, does that not mean no-op?
k
e.g. List<x> vs. ImmutableList<x>
z
I think this is a compiler issue. I might be missing something but I have a very minimal test showing that simply adding an optional parameter to a composable function seems to make it non-skippable. I don’t think that’s how it should work?
u
by optional you mean param with default value? concretely all these?
Copy code
@Composable
fun Image(
    painter: Painter,
    contentDescription: String?,
    modifier: Modifier = Modifier, <------
    alignment: Alignment = Alignment.Center, <------
    contentScale: ContentScale = ContentScale.Fit, <------
    alpha: Float = DefaultAlpha, <------
    colorFilter: ColorFilter? = null <------
) {
z
Yes