Мобильная разработка
Flutter
2018 год. Google выпускает Flutter 1.0. Главный вопрос разработчиков: зачем ещё один cross-platform фреймворк? Ответ оказался неожиданным - Flutter не использует нативные компоненты вообще. Skia рисует каждый пиксель самостоятельно. Спорное решение стало конкурентным преимуществом.
- Google Pay полностью переписан на Flutter - единый codebase для iOS и Android, pixel-perfect дизайн без platform-specific хаков
- BMW App (My BMW) использует Flutter для vehicle control UI - 3.5 миллиона загрузок, вышел одновременно на iOS и Android
- eBay Motors: Flutter для photo listing feature - скорость разработки в 2x по сравнению с нативными командами
Widget Tree: всё есть виджет
Flutter рендерит UI через собственный движок Skia/Impeller - без нативных компонентов. Каждый пиксель рисует Flutter. Widget - неизменяемое описание части UI. При изменении состояния Flutter пересоздаёт widget tree и передаёт Skia список drawing operations.
Три типа дерева: Widget tree (описание, immutable), Element tree (lifecycle, persistent), RenderObject tree (layout + paint). Flutter reconciliation: diffing Element tree, только изменённые ветки перерисовываются. Аналог React Virtual DOM, но для Dart объектов.
Почему Flutter рисует собственные пиксели вместо нативных UI компонентов?
State Management: BLoC, Riverpod, Provider
Flutter экосистема имеет несколько конкурирующих state management решений. BLoC (Business Logic Component) - Google's recommendation: Streams + events, хорошо для сложных приложений. Riverpod - современная альтернатива Provider с compile-time safety. setState - только для локального UI состояния.
Riverpod 2.0 добавил code generation и @riverpod аннотации - compile-time safety без ProviderScope ошибок в runtime. Google Pay, eBay, BMW App используют Flutter с BLoC. Выбор: BLoC для enterprise (тестируемость), Riverpod для продуктовых команд (DX), setState для прототипов.
Когда setState достаточно, а когда нужен BLoC или Riverpod?
Dart: язык Flutter экосистемы
Dart компилируется в нативный ARM/x64 (AOT для production), или в JavaScript (Flutter Web), или работает в Dart VM с JIT (debug mode для hot reload). Null safety с 2021 года: типы non-nullable по умолчанию, компилятор проверяет null на этапе сборки.
Почему Flutter использует Dart Isolates вместо обычных потоков для CPU-intensive задач?
Platform Channels: доступ к нативному API
Platform Channels - механизм коммуникации Flutter с нативным кодом iOS/Android через асинхронный message passing. MethodChannel для вызовов, EventChannel для потоков событий (sensors, location). Стандарт кодирования: StandardMessageCodec (типы Dart <-> нативные).
Чем EventChannel отличается от MethodChannel в Flutter?
Ключевые идеи
- Widget tree - неизменяемые описания UI; Flutter reconciliation сравнивает Element tree, перерисовывает только изменения.
- Dart Isolates: изолированная память, message passing - нет race conditions, параллельные CPU задачи безопасно.
- Platform Channels: MethodChannel для одиночных вызовов, EventChannel для потоков - мост к нативному iOS/Android API.
Связанные темы
Flutter решает ту же проблему что и React Native, но другим способом:
- React Native — Альтернативный cross-platform подход: нативные компоненты через Bridge vs собственный рендерер Flutter
- Unit и UI Testing — Flutter widget testing: flutter_test позволяет тестировать виджеты без реального устройства через WidgetTester
Вопросы для размышления
- В каких сценариях собственный рендерер Flutter - преимущество, а когда - недостаток по сравнению с нативными компонентами?
- Как Dart Isolates концептуально похожи на Erlang акторов и Go горутины?
- Почему несмотря на единый codebase Flutter приложения требуют platform-specific тестирования?