В каких случаях Jetpack Compose считает аргумент стабильным или нестабильным
Что проверяют
Понимаете ли вы, когда Compose пропускает рекомпозицию функции, и умеете ли искать причину лишних рекомпозиций. Следом спросят про strong skipping mode и про то, как проверить стабильность конкретного класса.
Как отвечать
Стабильность это контракт типа: equals для двух экземпляров всегда даёт один и тот же результат, а если публичное свойство меняется, Compose об этом узнаёт. Если все параметры функции стабильны и равны прошлым значениям, рекомпозиция пропускается.
Компилятор Compose выводит стабильность сам:
- стабильны: примитивы,
String, функциональные типы,enum, классы, у которых все публичные свойстваvalстабильных типов, иMutableState<T>, потому что изменения в нём отслеживаются; - нестабильны: классы с публичным
var, интерфейсыList,Set,Mapиз стандартной библиотеки Kotlin (за ними может стоять изменяемая реализация), классы из модулей, собранных без компилятора Compose, например domain-модуль или сторонняя библиотека; - зависят от параметров: обобщённые типы вроде
Pair<A, B>стабильны, если стабильны аргументы.
Как управлять: аннотации @Immutable и @Stable (это обещание разработчика, компилятор его не проверяет), ImmutableList из kotlinx.collections.immutable, файл конфигурации стабильности в Compose Compiler Gradle plugin для чужих классов. Проверять через отчёты компилятора (стабильность классов, skippable у функций) и счётчики рекомпозиций в Layout Inspector.
Скажите про strong skipping mode: он включён по умолчанию начиная с Kotlin 2.0.20. В нём функции с нестабильными параметрами тоже пропускаются: нестабильные сравниваются по ссылке (===), стабильные через equals, а лямбды запоминаются автоматически.
Где спотыкаются
Называют data class стабильным всегда. Одно свойство var или поле типа List<T> делают его нестабильным.
Вешают @Immutable на класс с изменяемыми полями ради зелёного отчёта. Compose поверит, пропустит рекомпозицию, и экран покажет устаревшие данные.
Отвечают по правилам до strong skipping и считают, что нестабильный параметр запрещает пропуск всегда. Сейчас важнее другое: новый экземпляр при каждой рекомпозиции ломает сравнение по ссылке.