Стабильность в Compose

Compose считает типы либо стабильными, либо нестабильными. Тип является стабильным, если он неизменяем или если Compose может узнать, изменилось ли его значение между рекомпозициями. Тип нестабильен, если Compose не может знать, изменилось ли его значение между рекомпозициями.

Compose использует стабильность параметров составного объекта, чтобы определить, может ли он пропустить составной объект во время рекомпозиции :

  • Стабильные параметры: если составной объект имеет стабильные параметры, которые не изменились, Compose пропускает его.
  • Нестабильные параметры: если составной объект имеет нестабильные параметры, Compose всегда перекомпоновывает его при перекомпоновке родителя компонента.

Если ваше приложение включает в себя множество неоправданно нестабильных компонентов, которые Compose всегда перекомпоновывает, вы можете наблюдать проблемы с производительностью и другие проблемы.

В этом документе подробно описано, как можно повысить стабильность вашего приложения, чтобы улучшить производительность и общее удобство для пользователей.

Неизменяемые объекты

Следующие фрагменты демонстрируют общие принципы стабильности и рекомпозиции.

Класс Contact — это неизменяемый класс данных. Это связано с тем, что все его параметры являются примитивами, определяемыми ключевым словом val . После создания экземпляра Contact вы не сможете изменить значения свойств объекта. Если бы вы попытались это сделать, вы бы создали новый объект.

data class Contact(val name: String, val number: String)

Составной элемент ContactRow имеет параметр типа Contact .

@Composable
fun ContactRow(contact: Contact, modifier: Modifier = Modifier) {
   var selected by remember { mutableStateOf(false) }

   Row(modifier) {
      ContactDetails(contact)
      ToggleButton(selected, onToggled = { selected = !selected })
   }
}

Рассмотрим, что происходит, когда пользователь нажимает кнопку переключения и selected состояние меняется:

  1. Compose оценивает, следует ли перекомпоновать код внутри ContactRow .
  2. Он видит, что единственный аргумент ContactDetails имеет тип Contact .
  3. Поскольку Contact является неизменяемым классом данных, Compose уверен, что ни один из аргументов ContactDetails не изменился.
  4. Таким образом, Compose пропускает ContactDetails и не перекомпоновывает их.
  5. С другой стороны, аргументы ToggleButton изменились, и Compose перекомпонует этот компонент.

Изменяемые объекты

Хотя в предыдущем примере используется неизменяемый объект, можно создать изменяемый объект. Рассмотрим следующий фрагмент:

data class Contact(var name: String, var number: String)

Поскольку каждый параметр Contact теперь является var , класс больше не является неизменяемым. Если его свойства изменятся, Compose не узнает об этом. Это связано с тем, что Compose отслеживает только изменения в объектах Compose State .

Compose считает такой класс нестабильным. Compose не пропускает рекомпозицию нестабильных классов. Таким образом, если бы Contact был определен таким образом, ContactRow в предыдущем примере перекомпоновал бы любое selected изменение.

Реализация в Compose

Может быть полезно, хотя и не критично, рассмотреть, как именно Compose определяет, какие функции пропускать во время рекомпозиции.

Когда компилятор Compose запускается над вашим кодом, он помечает каждую функцию и тип одним из нескольких тегов. Эти теги отражают, как Compose обрабатывает функцию или тип во время рекомпозиции.

Функции

Compose может помечать функции как skippable или restartable . Обратите внимание, что он может пометить функцию как одну, обе или ни одну из них:

  • Пропускаемый : если компилятор помечает компонуемый объект как пропускаемый, Compose может пропустить его во время рекомпозиции, если все его аргументы равны своим предыдущим значениям.
  • Перезапускаемый : составной объект, который можно перезапускать, служит «областью», где может начаться рекомпозиция. Другими словами, функция может быть точкой входа, где Compose может начать повторное выполнение кода для рекомпозиции после изменения состояния.

Типы

Составление помечает типы как неизменяемые или стабильные. Каждый тип является тем или иным:

  • Immutable : Compose помечает тип как неизменяемый, если значение его свойств никогда не может измениться и все методы ссылочно прозрачны.
    • Обратите внимание, что все примитивные типы помечены как неизменяемые. К ним относятся String , Int и Float .
  • Стабильный : указывает тип, свойства которого могут измениться после создания. Если и когда эти свойства изменяются во время выполнения, Compose узнает об этих изменениях.

Отладка стабильности

Если ваше приложение перекомпонует составной объект, параметры которого не изменились, сначала проверьте его определение на наличие параметров, которые явно изменяемы. Compose всегда перекомпонует компонент, если вы передаете тип со свойствами var или свойство val , использующее известный нестабильный тип.

Подробную информацию о том, как диагностировать сложные проблемы со стабильностью в Compose, см. в руководстве по стабильности отладки .

Исправить проблемы со стабильностью

Сведения о том, как обеспечить стабильность реализации Compose, см. в руководстве по устранению проблем со стабильностью .

Краткое содержание

В целом, следует обратить внимание на следующие моменты:

  • Параметры : Compose определяет стабильность каждого параметра ваших составных объектов, чтобы определить, какие составные элементы следует пропускать во время рекомпозиции.
  • Немедленные исправления : если вы заметили, что ваш составной объект не пропускается и вызывает проблемы с производительностью , вам следует сначала проверить очевидные причины нестабильности, такие как параметры var .
  • Отчеты компилятора . Вы можете использовать отчеты компилятора , чтобы определить, насколько стабильны ваши классы.
  • Коллекции : Compose всегда считает нестабильными классы коллекций, такие как List, Set и Map . Это связано с тем, что невозможно гарантировать, что они неизменяемы. Вместо этого вы можете использовать неизменяемые коллекции Kotlinx или аннотировать свои классы как @Immutable или @Stable .
  • Другие модули : Compose всегда считает нестабильными те модули, в которых компилятор Compose не запускается. При необходимости оберните классы в классы модели пользовательского интерфейса.

Дальнейшее чтение