← Назад к вопросам

Как работает @Restartable в Jetpack Compose?

2.7 Senior🔥 41 комментариев
#UI и вёрстка#Архитектура и паттерны

Комментарии (1)

🐱
deepseek-v3.2PrepBro AI5 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Обзор аннотации @Restartable в Jetpack Compose

Аннотация @Restartable является частью системы управления состоянием Jetpack Compose, а точнее — модуля Compose Runtime. Это низкоуровневая аннотация, используемая преимущественно разработчиками библиотек и в сложных сценариях оптимизации. Её основное назначение — пометить композейбл-функцию как перезапускаемую, что даёт Compose-рантайму больше гибкости при принятии решения о необходимости рекомпозиции.

Принцип работы и взаимодействие с системой рекомпозиции

В основе Jetpack Compose лежит реактивная модель: когда изменяются входные данные (State), Compose автоматически перезапускает (рекомпозирует) затронутые композейбл-функции, чтобы обновить UI. Рантайм Compose строит граф рекомпозиции, где узлами являются группы (Group), хранящие информацию о вызовах композейбл-функций и их состоянии.

import androidx.compose.runtime.*

// 1. Обычный композейбл, неявно перезапускаемый.
@Composable
fun Greeting(name: String) {
    Text(text = "Hello, $name!")
}

// 2. Явное использование @Restartable (на практике редко требуется вручную).
@Restartable // Явное указание для рантайма
@Composable
fun RestartableGreeting(name: State<String>) {
    Text(text = "Hello, ${name.value}!")
}

Ключевые аспекты:

  • Неявное применение: Подавляющее большинство обычных композейбл-функций автоматически считаются перезапускаемыми. Compose-компилятор анализирует код и добавляет эту аннотацию там, где это необходимо. Ручное использование @Restartable в повседневной разработке встречается крайне редко.
  • Гранулярность рекомпозиции: Основная ценность явного указания @Restartable (или её "партнёрской" аннотации @NonRestartable) проявляется в оптимизации. Пометив функцию как перезапускаемую, вы даёте рантайму понять, что её можно рекомпозировать независимо от родительской функции, если изменились только её собственные параметры. Это может помочь избежать избыточной рекомпозиции родительских областей.
  • Связь с @Skip и @NonRestartable: Аннотации @SkipToEnd и @NonRestartable используются для объединения группы с родительской, делая их рекомпозицию неделимой. @Restartable — это их противоположность. Она явно указывает, что функция является отдельной точкой входа для перезапуска в графе композиции.
// Упрощённая иллюстрация логики рантайма
if (composableFunction.isRestartable && inputsChanged) {
    // Перезапускаем только эту конкретную функцию или её область
    recomposeScope()
} else {
    // Возможно, потребуется подняться выше по дереву композиции
}

Практическое применение и рекомендации

  1. Для разработчиков приложений: Вам почти никогда не нужно использовать @Restartable напрямую. Compose-компилятор отлично справляется с оптимизацией. Ваша задача — правильно использовать State, remember, derivedStateOf и другие примитивы для создания стабильных входных данных (@Stable), что является гораздо более эффективным способом управления рекомпозицией.

  2. Для разработчиков библиотек: Это основной сценарий использования. При создании сложных кастомных композейбл-функций или низкоуровневых API, где критичен контроль над графом рекомпозиции, @Restartable может быть частью набора инструментов для точной настройки поведения. Например, вы можете гарантировать, что ваш композейбл будет перезапускаться только при изменении конкретных ключей, даже если его родитель рекомпозируется чаще.

  3. Оптимизация производительности: В очень специфичных случаях, при профилировании и обнаружении избыточной рекомпозиции больших блоков кода, можно рассмотреть явную разметку. Но это должно быть исключением, подтверждённым данными профилировщика.

// Пример гипотетической оптимизации (очень упрощённо)
@Restartable
@Composable
fun ExpensiveDataTable(data: List<DataItem>, config: TableConfig) {
    // Логика отрисовки сложной таблицы
    // Благодаря @Restartable, если изменится только config, а data останется прежней,
    // рантайм может (но не обязан!) принять более оптимальное решение.
}

Важное предупреждение

Некорректное использование низкоуровневых аннотаций, таких как @Restartable, @NonRestartable, @Stable, может нарушить механизм рекомпозиции и привести к трудноотлавливаемым багам (необновляемый UI, лишние рекомпозиции). Всегда полагайтесь на встроенные оптимизации компилятора, если у вас нет глубокого понимания внутреннего устройства Compose Runtime.

Итог: @Restartable — это инструмент разметки графа рекомпозиции для Compose-рантайма. Она указывает, что функцию можно перезапустить независимо. Хотя в явном виде она используется редко, её концепция лежит в основе автоматической оптимизации Compose, обеспечивая эффективное и целевое обновление пользовательского интерфейса. Для большинства задач сосредоточьтесь на правильном управлении состоянием, а не на ручной расстановке этих аннотаций.