We have to mark our classes with a @StableMarker a...
# compose
m
We have to mark our classes with a @StableMarker annotated annotation in order to allow the compiler to perform the function skipping transformations. My question is why did you make this feature opt-in? We either have to annotate every class we use in compose with one of the annotations or we don't get the optimizations. Are there any plans to improve or change that behavior?
c
It is more than just saving the cost of
equals()
. For stable parameters the assumption is that we compare the previously passed values for all parameters and if
equals()
returns true then recomposition is unnecessary as the result will be the same as last time. This is certainly true for naturally immutable values, such as
String
and literals, but it is unclear for other data type. We use
@Immutable
so a developer can indicate that the values of a type should be treated as if they are immutable.
@Stable
can be used to indicate that, even though the type is not really immutable, it can be treated as one. For example
@Model
is marked with
@StableMarker
because it will invalidate the composition where it was read when it changes. We use
@Stable
when the type is not immutable but the changes cannot, or will not, be observed during composition.
Modifier
is the best example of this kind of type. The main motivation for
@Stable
and
@Immutable
markers today is correctness of the generated code. It ensures we only assume we can skip composition when the types involved know, and are signed up for, the contract they are expected to obey. In general, any object that can be mutated we should ignore the result of
equals()
for skipping, it will always be
true
even when the object has changed. Essentially we will be asking if
a.equals(a)
which should always be
true
. This doesn't tell us whether the composition will be the same for the value (as it won't be if the object is mutable and has changed) which is what we need to know for skipping. The exceptions for this are
@Model
or similar objects as composition observes changes in these objects, or
Modifiers
or similar objects where the mutations are not visible to composition (e.g. they are potentially updated with cached information during layout and draw) or object which are declared as mutable but generally are not (such as the result of deserialization from JSON or a protobuf). We have considered inferring
@Stable
some cases that seem reasonable such as any
data
class that has only public
val
properties, and any
enum
class also with public
val
properties (if any). Both involve a risk as a binary compatible change can be made to either of these types that adds a
var
property which invalidates the code generation assumptions we have made for these types. In other words, even though the JVM and DEX consider these binary compatible changes, we would not. As for the deserialization case we have some ideas along these lines but nothing concrete yet.
💯 1
👍 1