Сравнение показателей Compose и View

Jetpack Compose ускоряет разработку пользовательского интерфейса и улучшает разработку для Android. Однако учитывайте, что добавление Compose в существующее приложение может повлиять на такие показатели, как размер APK, сборка и производительность во время выполнения.

Размер APK-файла и время сборки

В этом разделе мы рассмотрим, как переход на Compose влияет на размер APK-файла и время сборки, на примере приложения Sunflower. Оно демонстрирует лучшие практики переноса приложения на основе View на Compose.

Размер APK-файла

Добавление библиотек в проект увеличивает размер APK. Ниже приведены результаты для минифицированного APK-файла каждого проекта с включенным сокращением ресурсов и кода, использующего полный режим R8 и измеренного с помощью APK Analyzer.

Только просмотры Смешанные представления и Compose Только создание
Размер загрузки 2252 КБ 3034 КБ 2966 КБ

При первом добавлении Compose в Sunflower размер APK увеличился с 2252 КБ до 3034 КБ – на 782 КБ. Сгенерированный APK-файл содержал пользовательский интерфейс, созданный с помощью View и Compose. Это ожидаемо, поскольку в Sunflower были добавлены дополнительные зависимости.

И наоборот, когда Sunflower было переведено на Compose, размер APK уменьшился с 3034 до 2966 КБ, то есть на 68 КБ. Это уменьшение было связано с удалением неиспользуемых зависимостей View, таких как AppCompat и ConstraintLayout.

Время на сборку

Добавление Compose увеличивает время сборки приложения, поскольку компилятор Compose обрабатывает composable-функции. Следующие результаты были получены с помощью автономного инструмента gradle-profiler, который выполняет сборку несколько раз, чтобы можно было получить среднее время сборки для отладочной сборки Sunflower:

gradle-profiler --benchmark --project-dir . :app:assembleDebug
Только просмотры Смешанные представления и Compose Только создание
Среднее время сборки 299,47 мс 399,09 мс 342,16 мс

При первом добавлении Compose в Sunflower среднее время сборки увеличилось с 299 мс до 399 мс – на 100 мс. Это связано с тем, что компилятор Compose выполняет дополнительные задачи по преобразованию кода Compose, определенного в проекте.

И наоборот, среднее время сборки сократилось до 342 мс (на 57 мс), когда переход Sunflower на Compose был завершен. Это сокращение можно объяснить несколькими факторами, которые в совокупности сокращают время сборки, такими как удаление привязки данных, перенос зависимостей, использующих kapt, в KSP, и обновление нескольких зависимостей до их последних версий.

Сводка

Использование Compose увеличит размер APK-файла и время сборки приложения из-за процесса компиляции кода Compose. Однако эти компромиссы необходимо сопоставить с преимуществами Compose, особенно в отношении повышения продуктивности разработчиков при внедрении Compose. Например, команда Google Play обнаружила, что для создания интерфейса требуется гораздо меньше кода, иногда на 50%. Это повышает производительность и упрощает поддержку кода.

Другие примеры использования можно найти в статье Внедрение Compose для Teams.

Производительность во время выполнения

В этом разделе рассматриваются темы, связанные с производительностью во время выполнения в Jetpack Compose, чтобы помочь понять, как Jetpack Compose сравнивается с производительностью системы View и как вы можете ее измерить.

Умные рекомендации

Когда части пользовательского интерфейса недействительны, Compose пытается перекомпоновать только те части, которые необходимо обновить. Подробнее об этом рассказывается в документации по жизненному циклу composable-функций и этапам Jetpack Compose.

Профили базовой конфигурации

Базовые профили – отличный способ ускорить распространенные пути пользователей. Добавление базового профиля в приложение может повысить скорость выполнения кода примерно на 30% с первого запуска, поскольку для включенных путей выполнения кода не требуется интерпретация и JIT-компиляция.

Библиотека Jetpack Compose включает собственный профиль базовой конфигурации, и вы автоматически получаете эти оптимизации, когда используете Compose в своем приложении. Однако эти оптимизации влияют только на пути выполнения в библиотеке Compose, поэтому мы рекомендуем добавить профиль базовой конфигурации в приложение, чтобы охватить пути выполнения за пределами Compose.

Сравнение с системой View

Jetpack Compose имеет много улучшений по сравнению с системой View. Эти улучшения описаны в разделах ниже.

Все элементы расширяют View

Каждый объект View, который рисует на экране, например TextView, Button или ImageView, требует выделения памяти, явного отслеживания состояния и различных обратных вызовов для поддержки всех вариантов использования. Кроме того, владелец пользовательского View должен реализовать явную логику, чтобы предотвратить перерисовку, когда в этом нет необходимости, например для повторяющейся обработки данных.

Jetpack Compose решает эту проблему несколькими способами. В Compose нет явных обновляемых объектов для представлений чертежей. Элементы пользовательского интерфейса – это простые composable-функции, информация о которых записывается в композицию в воспроизводимом виде. Это позволяет ограничить явное отслеживание состояния, выделение памяти и обратные вызовы только теми composable-функциями, которым требуются эти функции, вместо того чтобы требовать их для всех расширений данного типа View.

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

Несколько проходов макета

Традиционные ViewGroups имеют большую выразительность в своих API-интерфейсах измерения и макета, что делает их склонными к нескольким проходам макета. Если это происходит в определенных вложенных точках иерархии View, объем работы может увеличиваться экспоненциально.

Jetpack Compose обеспечивает один проход макета для всех составных элементов макета через контракт API. Это позволяет Compose эффективно обрабатывать глубокие деревья пользовательского интерфейса. Если требуется несколько измерений, в Compose есть внутренние измерения.

Посмотреть производительность запуска

При первом показе макета система View должна распаковать XML-макеты. В Jetpack Compose этого не происходит, поскольку макеты написаны на Kotlin и компилируются вместе с остальными компонентами приложения.

Тестирование Compose

В Jetpack Compose 1.0 есть заметные различия между производительностью приложения в режимах debug и release. Чтобы получить репрезентативные данные о времени, при профилировании приложения всегда используйте сборку release, а не debug.

Чтобы проверить производительность кода Jetpack Compose, можно использовать библиотеку Jetpack Macrobenchmark. Чтобы узнать, как использовать его с Jetpack Compose, ознакомьтесь с проектом MacrobenchmarkSample.

Команда Jetpack Compose также использует Macrobenchmark для выявления возможных регрессий. Например, посмотрите тест производительности для LazyColumn и панель управления для отслеживания регрессий.

Установка профиля Compose

Поскольку Jetpack Compose – это несвязанная библиотека, она не использует Zygote, который предварительно загружает классы UI Toolkit и графические объекты системы View. Jetpack Compose 1.0 использует установку профиля для конечных сборок. Установщики профилей позволяют приложениям указывать критически важный код, который нужно компилировать заранее во время установки. Compose поставляется с правилами установки профиля, которые сокращают время запуска и количество задержек в приложениях Compose.