Мы собрали 20 лет заметок о световой живописи в один гид. Он бесплатный. Читать гид ×
× ПриложенияТехнологииГалерея БлогО студииНаписать нам ›
Главная/Блог/Кросс-платформенная разработка и производительность графики: когда Flutter и React Native не подходят творческому iOS-приложению
Технологии

Кросс-платформенная разработка и производительность графики: когда Flutter и React Native не подходят творческому iOS-приложению

Разработчик творческого iOS-приложения — со светом, частицами, AR-эффектами или камерой в реальном времени — рано или поздно выбирает между нативным Swift-рендером и кросс-платформенным фреймворком. Для экрана со списками и формами разница почти не заметна. Но как только в кадре появляется GPU-нагруженная графика, ставки резко растут: команда, которая рассматривает кроссплатформенную разработку под ключ для творческого продукта, должна заранее понимать, где именно кросс-платформенные движки теряют кадры и когда это действительно критично.

TL;DR: Нативный Swift-рендер (Metal, Core Animation) держит прямой доступ к GPU, а Flutter (Skia/Impeller) и React Native (JS-мост) добавляют накладные расходы — особенно заметные на частицах, AR-эффектах и обработке камеры в реальном времени. Для типового бизнес-экрана это не критично. Для GPU-тяжёлой творческой графики чаще работает гибрид: кросс-платформенный каркас плюс native-модуль для самого рендера.
Руки держат iPhone рядом с ноутбуком, на обоих экранах светятся абстрактные частицы и линии — сравнение рендеринга

Что на самом деле измеряет «производительность» в графическом iOS-приложении?

Когда говорят «Flutter быстрее React Native» или «native быстрее всех», чаще всего имеют в виду синтетические CPU-тесты: сортировку массивов, математику, холодный старт приложения. Это легко измерить и опубликовать, но для творческого приложения такая метрика почти бесполезна.

GPU-нагруженная графика — частицы, слои с альфа-смешиванием, обработка кадра с камеры в реальном времени — упирается не в CPU, а в рендер-пайплайн: сколько слоёв и эффектов движок успевает собрать и передать на экран за 16 миллисекунд (60 кадров в секунду) или ещё быстрее на дисплеях с ProMotion. Здесь важен не язык программирования сам по себе, а то, насколько прямой путь у фреймворка от кода приложения до GPU.

Native в этом контексте — разработка на Swift с прямым доступом к Metal и Core Animation, где рендер-инструкции идут к GPU почти без промежуточных слоёв. Flutter компилирует интерфейс в собственный движок отрисовки (Skia, с постепенным переходом на Impeller), который рисует каждый пиксель сам, в обход нативных UI-компонентов платформы. React Native, в отличие от обоих, исторически использует мост (bridge) между JavaScript-потоком и нативным рендерингом — и именно этот мост чаще всего становится узким местом для анимации в реальном времени.

Почему Flutter и React Native теряют кадры на частицах, слоях и реал-тайм камере

Эта статья разбирает не общее сравнение технологий — его можно найти в материале про общее сравнение Swift и React Native — а узкий, но критичный для творческих приложений срез: производительность именно GPU-рендеринга.

Как рендерит нативный iOS (Metal, Core Animation, Core Image)

Swift-приложение может обращаться к Metal напрямую — низкоуровневому графическому API Apple, который даёт контроль над GPU почти на уровне драйвера. Core Animation берёт на себя композитинг слоёв (тени, прозрачность, трансформации) уже на GPU, а Core Image — готовый набор GPU-фильтров для обработки видео и фото в реальном времени, включая поток с камеры. Для системы частиц или сложной многослойной анимации это означает минимум прослоек между логикой приложения и отрисованным кадром.

Как рендерит Flutter (Skia/Impeller) и React Native (bridge/JS-поток)

Flutter вообще не использует нативные UI-компоненты платформы — он рисует собственный интерфейс через движок Skia или Impeller, который Apple и команда Flutter постепенно делают дефолтным на iOS именно ради более предсказуемой производительности шейдеров. Для статичного и умеренно анимированного UI это быстро и стабильно. Но тяжёлые системы частиц с сотнями объектов и кастомными шейдерами упираются в накладные расходы самого движка — он не имеет такого прямого доступа к Metal-примитивам, как Swift-код.

React Native устроен иначе: JavaScript-логика приложения исторически общалась с нативным рендерингом через асинхронный мост, сериализуя данные при каждом обновлении. Новая архитектура (Fabric и JSI) убрала часть этих накладных расходов, но для графики, которая обновляется 60 и более раз в секунду — частицы, слои, кадры с камеры, — узкое место чаще оказывается именно в частоте и объёме данных, которые нужно гонять между JS-потоком и нативным рендером.

Где именно это заметно: частицы, AR/ARKit-эффекты, обработка кадров камеры в реальном времени

Разница редко видна на глаз в статичном интерфейсе — она проявляется в конкретных сценариях: система из нескольких сотен частиц, которая должна держать 60 кадров в секунду; AR-эффект, где каждый кадр с камеры нужно анализировать и дорисовывать поверх в реальном времени (подробнее — в материале про ARKit в творческих приложениях); многослойная светокомпозиция, как в приложениях световой живописи, где десятки полупрозрачных слоёв накладываются друг на друга покадрово. Именно в этих сценариях разница между native-рендером и кросс-платформенным движком превращается из цифры в бенчмарке в заметное на глаз подёргивание кадра.

Плюсы и минусы каждого подхода для творческого приложения

Выбор редко сводится к «Flutter плохой, native хороший» — у каждого подхода есть сценарии, где он объективно выигрывает.

КритерийFlutter / React NativeNative Swift
Скорость разработки MVPВыше — одна кодовая база под iOS и AndroidНиже — отдельная реализация под каждую платформу
Бизнес-экраны (списки, формы, API)Разница в производительности практически не заметнаИзбыточно для этой задачи
Частицы, слои, AR, камера в реальном времениРиск просадки FPS на сложных сценахПрямой доступ к Metal и Core Animation
Бюджет и командаОдин фронтенд-стек, проще найти специалистовНужен iOS-инженер с опытом Metal или SceneKit

Когда Flutter/React Native — рабочий выбор

Если творческий функционал — не единственная и не главная часть приложения, а бюджет и срок выхода на рынок важнее идеальной плавности одного экрана, кросс-платформенный каркас — разумный выбор. Он особенно оправдан, когда продукт выходит сразу на iOS и Android, а графически тяжёлых сцен немного и они не требуют 120 кадров в секунду.

Когда нужен native/гибридный подход с native-модулями под рендер

Если творческая графика — это и есть продукт (как в приложениях световой живописи, AR-рисовании или обработке кадра с камеры в реальном времени), риск просадки кадров на кросс-платформенном движке становится риском для всего пользовательского опыта. В этом случае либо пишут native-приложение целиком, либо — чаще — выносят именно тяжёлый по графике экран в native-модуль, оставляя остальной интерфейс на кросс-платформенном каркасе.

Гибридный путь: native-модуль для рендера + кросс-платформенный каркас для остального

Полностью переписывать приложение на native из-за одного графически тяжёлого экрана — редко лучшее решение по деньгам и срокам. Более практичный путь — гибридная архитектура: основной UI, навигация и бизнес-логика остаются на Flutter или React Native, а конкретный экран с частицами, AR-эффектом или обработкой камеры рендерится нативным Swift-модулем через Metal или Core Image.

Технически это делается через platform channel (Flutter) или native-модуль с UIView (React Native): нативный код рисует кадр в отдельную текстуру или view, а кросс-платформенный слой встраивает её в общий интерфейс как обычный виджет. Для пользователя граница между «нативным» и «кросс-платформенным» куском экрана невидима — он просто видит плавную анимацию там, где она нужна. Для команды это означает, что основная часть разработки остаётся быстрой и единой для двух платформ, а инженерный ресурс на Metal или SceneKit нужен точечно, не для всего продукта сразу.

Как выбрать подход для своего проекта: чек-лист из 5 вопросов

  1. Сколько в приложении экранов с GPU-нагруженной графикой? Если это один-два экрана с эффектом, а остальное — обычный UI, разумно тестировать производительность именно на них, а не выносить вердикт по всему приложению сразу.
  2. Какую частоту кадров вы обещаете пользователю? 30 кадров в секунду кросс-платформенный движок почти всегда держит уверенно; 60 и тем более выше на сложных сценах — зона риска, которую стоит проверить прототипом до начала полноценной разработки.
  3. Нужен ли Android одновременно с iOS? Если да — кросс-платформенный каркас экономит реальные деньги на дублировании логики; если продукт стартует только на iOS, обоснование выбора Flutter или React Native становится слабее.
  4. Есть ли в команде инженер с опытом Metal, Core Animation или SceneKit? Гибридный путь требует этой компетенции хотя бы для одного native-модуля — без неё самый тяжёлый по графике экран рискует застрять на этапе разработки.
  5. Что случится, если графика всё-таки затормозит после запуска? Если переписать один экран на native-модуль можно без остановки всего проекта — риск кросс-платформенного старта управляем; если архитектура этого не допускает, native-рендер стоит закладывать сразу.

Часто задаваемые вопросы

Flutter быстрее React Native для графики?

В большинстве синтетических CPU-тестов разница между Flutter и React Native небольшая и зависит от конкретной задачи. Но для GPU-нагруженной графики у Flutter есть структурное преимущество: он рисует весь UI собственным движком (Skia/Impeller) и не зависит от моста между JavaScript-потоком и нативным рендером, как классический React Native. Поэтому на частицах и многослойной анимации Flutter чаще держит кадры стабильнее, хотя оба фреймворка проигрывают native Swift на самых тяжёлых сценах.

Можно ли использовать Metal из Flutter?

Напрямую — нет: Flutter не даёт доступа к Metal из Dart-кода. Но можно подключить native-модуль на Swift, который рендерит через Metal в отдельную текстуру, и передать готовый кадр во Flutter через platform channel или Texture widget. Это и есть гибридный путь: сложная графика считается нативно, а остальной интерфейс остаётся на Flutter.

Что выбрать для AR-приложения: native или кросс-платформенный фреймворк?

Для iOS-only AR-продукта с кастомными эффектами логичнее начинать с ARKit и native-рендера — это даёт прямой доступ к occlusion, light estimation и системам частиц без промежуточных слоёв. Кросс-платформенный путь оправдан, если AR — не основная механика, а одна из многих функций приложения на двух платформах сразу.

Сколько стоит переписать кросс-платформенное приложение на native из-за производительности?

Полный переход на native обычно дороже, чем точечный: написать native-модуль под один графически тяжёлый экран и оставить остальной Flutter или React Native UI как есть. Стоимость точечного переписывания зависит от сложности эффекта, но она на порядок ниже полной миграции приложения — и именно поэтому гибридный подход почти всегда выгоднее с самого начала.

Подходит ли React Native для приложений с камерой в реальном времени?

Для базовых сценариев — снять фото, применить готовый фильтр — да. Для обработки видеопотока с камеры в реальном времени с кастомными эффектами (сегментация, частицы, AR-наложение) мост React Native становится узким местом: такие задачи почти всегда выносят в native-модуль через Core Image или Metal, а React Native остаётся оболочкой для остального интерфейса.

Impeller решает проблему производительности Flutter полностью?

Impeller убирает конкретную проблему — просадки кадров при первой компиляции шейдеров (shader jank), которая была заметна именно на iOS при использовании Skia. Это ощутимо улучшает плавность, но не даёт Flutter прямого доступа к Metal-примитивам на уровне Swift-кода — для самых тяжёлых сцен с сотнями частиц разница с native-рендером остаётся.

Абстрактные светящиеся линии и частицы на тёмном фоне — визуализация GPU-рендер-пайплайна

Выбор между Flutter, React Native и native Swift для творческого iOS-приложения — это не вопрос «что лучше вообще», а вопрос, где именно в продукте живёт GPU-нагруженная графика. Для бизнес-экранов кросс-платформенный каркас почти всегда экономит время и деньги без заметной потери качества. Для частиц, AR-эффектов и камеры в реальном времени разумнее сразу закладывать native-модуль под самый тяжёлый экран — и тестировать его на реальном устройстве, а не полагаться на цифры из общих бенчмарков.

Есть вопрос по теме?

Напишите нам — с удовольствием разберём ваш случай и, может быть, сделаем из него следующую статью.

xdt_software@oodot.com ›