Site icon AppTractor

Сравнение производительности Compose и View

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

Размер APK и время сборки

Здесь мы определим влияние добавления или миграции на Jetpack Compose для двух приложений:

Размер APK

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

Tivi уменьшил размер APK на 46%, с 4.49 МБ до 2.39 МБ. Кроме того, после полного перехода на Compose количество методов сократилось на 17%. Количество строк в XML уменьшилось на 76%.

В Sunflower при добавлении Compose размер APK увеличился на 19%, с 2 407 КБ до 2 982 КБ. Поскольку Compose практически не используется в этой ветке Sunflower, проект не получил преимуществ, связанных с размером Compose-only  APK, таких как удаление из проекта зависимости AppCompat.

Примечание: Цифры показывают размер APK-файла, а не размер загрузки — из APK Analyzer.

Время сборки

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

Примечание: Для запуска тестов используется следующая команда Gradle после кэширования всех удаленных артефактов. При этом учитывается время debug сборки, которое может быть более важным при разработке.

./gradlew --profile --offline --rerun-tasks --max-workers=4 assembleDebug

Среднее время сборки Tivi до перехода на Compose составляло 108.71 секунды. После полного перехода на Compose среднее время сборки уменьшилось до 76.96 секунды — на 29%. На это сокращение времени в значительной степени повлияло то, что Hilt стал быстрее в Android Gradle Plugin 7.0, а также то, что из проекта удалось убрать дата биндинг и Epoxy, который использует процессоры аннотаций kapt.

А вот у Sunflower медианное время сборки увеличилось на 7.6% — с 11.57 до 12.45 секунды.

Заключительные мысли

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

Примечание: Во время перехода Tivi на Compose произошло множество обновлений зависимостей, таких как Gradle (с 6.0.1 до 7.1.1), Android Gradle Plugin (с 3.6.0 до 7.1.0-alpha02) и Kotlin (с 1.3.61 до 1.5.0), что может влиять на размер APK и время сборки.

Более подробную информацию о показателях Tivi после перехода на Compose можно найти в статье “Jetpack Compose — до и после”.

Производительность рантайма

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

Интеллектуальные рекомпозиции

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

Базовые профили

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

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

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

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

Все расширяет View

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

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

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

Несколько проходов компоновки

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

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

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

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

Бенчмарк Compose

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

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

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

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

Поскольку Jetpack Compose — это непривязанная библиотека, она не использует возможности Zygote, которая предварительно загружает классы UI Toolkit и drawable View-системы. В Jetpack Compose 1.0 для релизных сборок используется установка профилей. Профильные инсталляторы позволяют приложениям указывать критический код, который должен быть скомпилирован заранее (AOT) во время установки. Compose поставляет правила установки профилей, которые сокращают время запуска и уменьшают количество ошибок в приложениях Compose.

Примечание: Профили Compose недоступны на Android L или M, поскольку на устройствах этих версий приложение компилируется AOT с помощью Android Framework. Более подробно об этом рассказано в видеоролике “Делаем приложение быстрым с Baseline Profiles”:

Источник

Exit mobile version