Давайте возьмём задачи разной сложности и сравним потребление памяти, FPS, загрузку CPU и GPU при работе мобильных приложений, созданных с помощью разных технологий.
Предыстория
Мы постоянно изучаем производительность кроссплатформенных мобильных решений, доступных на рынке. Мы хотим знать, какая технология лучше всего подходит для разработки того или иного продукта.
В этой статье мы решили исследовать производительность при отрисовке графического интерфейса, которая имеет большое значение для пользователей мобильных приложений. Говоря простыми словами, любые тормоза будут видны невооружённым глазом.
Измерение производительности пользовательского интерфейса — сложная задача, требующая одинаковой реализации одной и той же функциональности на всех платформах. В качестве инструмента для тестирования мы использовали GameBench, чтобы быть уверенными в своей объективности (это не меняет того факта, что мы действительно любим Flutter, и по-прежнему делаем множество проектов на React Native, а также занимаемся нативной разработкой). Нам удалось поместить каждое приложение в единое тестовое окружение.
Исходный код открыт, поэтому, если хотите, поэкспериментируйте и поделитесь своими мыслями с нами. В UI-анимациях в зависимости от платформы используются разные инструменты, поэтому мы сузили наш скоуп до библиотек, поддерживаемых каждой платформой (кроме одного случая), или, по крайней мере, мы сделали все возможное, чтобы добиться этого. Результаты тестирования могут отличаться и зависеть от ваших подходов к реализации. Мы рассчитаем, что вы, как истинный эксперт в той или иной технологии, можете подобрать и настроить свой набор инструментов, которые обеспечат более высокие показатели. Мы будем рады, если вы это сделаете и расскажете, что получилось.
О железе
Для тестовых целей мы использовали Xiaomi Redmi Note 5 и iPhone 6s.
Ссылка на репозиторий: Source code
Тест 1: List view
Мы реализовали один и тот же интерфейс нативно (на Android и iOS), на React Native и на Flutter. Мы также автоматизировали скорость прокрутки с помощью RecyclerView.SmoothScroller на Android. На iOS и React Native мы использовали таймер и программную прокрутку. На Flutter мы использовали ScrollController для плавной прокрутки списка. В каждом случае у нас в списке было 1000 элементов, и мы зафиксировали одинаковое время прокрутки до последнего элемента списка. В каждом из этих случаев мы использовали кэширование изображений с разными библиотеками для каждой платформы. Более подробная информация есть в исходном коде.
Библиотеки для загрузки и кэширования изображений
iOS
Android
React Native
К сожалению, бенчмарк не выдаёт результаты GPU тестов для Android-устройств. Мы пробовали разные, но увы.
Остальные результаты тестов для Android
- Все тесты показали примерно одинаковый FPS.
- Android Native использует вдвое меньше памяти по сравнению с Flutter и React Native.
- React Native требует наибольшего использования процессора. Причина заключается в использовании JS Bridge между JS и Native code, что приводит к потере ресурсов на сериализацию и десериализацию.
- Что касается эксплуатации батареи, Android Native имеет лучший результат. React Native отстаёт как от Android, так и от Flutter. Запуск непрерывной анимации потребляет больше энергии аккумулятора на React Native.
Результаты тестов для iPhone 6s
- FPS. У React Native результаты хуже, чем у Flutter и Swift. Причина заключается в невозможности использования IoT-компиляции на iOS.
- Объём памяти. Flutter сопоставим со Swift в плане потребления памяти, но сильнее грузит процессор. В этом тесте React Native сильно отстаёт от Flutter и Swift.
- Flutter vs Swift: Flutter активно использует CPU, Swift активно использует GPU.
Тест 2: Тяжелая анимация
В настоящее время большинство телефонов, работающих на Android и iOS, имеют мощное железо. В большинстве случаев, при использовании обычных бизнес-приложений, не было замечено никаких падений FPS. Вот почему мы решили провести несколько тестов с тяжёлой анимацией. Для создания векторной анимации мы использовали Lottie для Android, iOS, React Native и Flare — для Flutter:
Lottie for Android, iOS, React Native и Flare for Flutter.
Результаты тестов для Android
- Android Native и React Native сопоставимы по производительности. Это очевидно, потому что Lottie для React Native использует нативные вызовы (16–19% CPU, 30–29 FPS).
- Результат Flutter удивил, хотя он немного облажался во время тестирования (12% CPU и 9 FPS).
- Android Native требует наименьшего объёма памяти (205 Мб); React Native требует 280 Мб, а Flutter — 266 Мб.
- Холодный старт приложения. По этому показателю Flutter является лидером (2 секунды). Для Android Native и React Native он занимает около 4 секунд.
Мы обнаружили, что удаление одной анимации из сетки увеличивает FPS до 40% у Flutter. Мы предполагаем, что Flare тяжёл и недостаточно оптимизирован для такого рода задач. Вот поэтому у Flutter и было такое падение FPS.
Посмотрите на это:
Результаты тестов для iOS
- Результаты iOS и React Native в этом тесте почти такие же, как у Lottie для React Native.
- Flare с Flutter не перестают удивлять. Flare в этом тесте вообще молодец!
- Нативный код для iOS здесь требует наименьшего объёма памяти (48 Мб). React Native требует 135 Мб, а Flutter — 117 Мб;
- Холодный старт приложения. По этому показателю Flutter является лидером (2 секунды). Для нативного кода iOS и React Native он занимает около 10 секунд.
Обратите внимание: здесь мы использовали с Flutter другую библиотеку, которая намного тяжелее по сравнению с теми, что мы использовали для других платформ, и это может быть причиной падения FPS для Flutter.
Тест 3: Тяжеленная анимация с вращениями, масштабированием и фейдингом
В этом тесте мы сравнили производительность анимации с 200 изображениями. Вращение и масштабирование выполняется одновременно.
Результаты тестов для Android
- Android Native показал высочайшую производительность и наиболее эффективное потребление памяти.
- Flutter показал очень близкий к Native fps и вдвое больший расход памяти, но всё же приличную производительность.
- React Native показал низкую производительность в этом тесте.
Результаты тестов для iOS
- iPhone 6s достаточно мощный, чтобы не допустить падения FPS во всех 3 случаях.
- Работа нативного кода потребовала меньше ресурсов, так как в основном использовался GPU.
- React Native для рендеринга в основном использовал процессор, а Flutter использовал GPU.
- Кроме того, React Native съел немного больше памяти.
Итоги тестирования
Для бизнес-приложений с обычной анимацией и красивым внешним видом выбор технологии для разработки не принципиален. Но если вам нужна тяжелая анимация, имейте в виду, что в этом случае наибольшую производительность обеспечит нативная разработка. Далее идёт Flutter, а затем React Native. Мы определённо не рекомендовали бы использовать React Native для задач, которые могут съесть много ресурсов процессора, в то время как Flutter отлично подходит для таких задач как с точки зрения процессора, так и с точки зрения памяти.
Выбор инструмента зависит от конкретного продукта и ситуации. Если вы хотите разработать MVP для одной платформы — можете выбрать нативную разработку, но имейте в виду, что Flutter позволяет создавать приложения как для мобильных устройств, так и для веба. Так что, возможно, Flutter в недалёком будущем станет лидером рынка кросс-платформенной разработки. Уже сегодня Flutter составляет очень достойную конкуренцию нативным инструментам разработки, особенно если ваш бюджет на разработку небольшой, но вы всё же хотите обеспечить приемлемый уровень производительности приложения.
Есть много факторов, влияющих на процесс и стандарты разработки для каждой технологии. Мы постарались максимально повысить прозрачность процесса, обеспечив единое тестовое окружение для каждого приложения и унифицированный набор инструментов для измерения производительности.
На правах рекламы
Нужен сервер для мобильного приложения? Присмотритесь к нашим эпичным серверам! Это серверы с новейшими процессорами AMD EPYC! Максимальная конфигурация позволит разместить проект любой сложности — 128 ядер CPU, 512 ГБ RAM, 4000 ГБ NVMe.
Автор: Mikhail