Что используется под капотом у Flutter?
Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Что используется под капотом у Flutter
Flutter — это сложная система с множеством слоёв абстракции. Понимание внутреннего устройства помогает писать более эффективный код и отлаживать проблемы.
Архитектура Flutter (слои)
Flutter устроен как многослойная система:
┌─────────────────────────────────────┐
│ Dart Framework (Widgets) │ ← что видит разработчик
│ (Material, Cupertino, etc.) │
├─────────────────────────────────────┤
│ Dart Runtime / Engine │
│ (Rendering, Animation, etc.) │
├─────────────────────────────────────┤
│ Engine (C++) │
│ (Skia, Text, Platform Channels) │
├─────────────────────────────────────┤
│ Embedder │
│ (iOS, Android, Web, Desktop) │
└─────────────────────────────────────┘
1. Dart Language и Runtime
Dart VM: Flutter использует Dart Virtual Machine — это JIT (Just-In-Time) компилятор для режима разработки и AOT (Ahead-Of-Time) компилятор для release.
- Development mode: Dart VM использует JIT, что позволяет Hot Reload
- Release mode: Код AOT-компилируется в нативный код (machine code)
- Web: Код компилируется в JavaScript
// Когда вы пишете это в Flutter
class MyWidget extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Text('Hello');
}
}
// Dart VM это парсит, анализирует типы, оптимизирует и выполняет
Garbage Collection: Dart имеет встроенный GC, автоматически управляющий памятью. Это означает, что вы не должны явно удалять объекты, но нужно избегать утечек.
2. Flutter Framework (Dart)
Это слой, с которым мы работаем ежедневно:
// Widgets — основные строительные блоки
Widget → RenderObject → Layer
// Примеры
Column() // Layout widget
Text() // Render widget
GestureDetector() // Input widget
StatefulWidget() // State management
Три деревья:
- Widget Tree — то, что вы создаёте в build() методе
- Element Tree — промежуточный слой управления состоянием
- Render Tree — объекты RenderObject для рендеринга
Когда вы меняете Widget, Flutter пересчитывает Element и Render деревья:
// Когда нажимаем кнопку
setState(() {
_counter++; // Trigger rebuild
});
// Происходит:
// 1. Widget tree перестраивается
// 2. Elements сравниваются (diffing) — старые Element остаются если тип совпадает
// 3. RenderObjects обновляются
// 4. Layer tree перестраивается
// 5. Skia на C++ выполняет рендеринг
3. Engine (C++)
Skia Graphics Library: Flutter использует Skia — мощную 2D графическую библиотеку, написанную на C++. Она отвечает за все графические операции.
Flutter Widgets
↓
Render Tree
↓
Layer Tree (Skia Canvas commands)
↓
Skia Rasterizer (растеризация в пиксели)
↓
Framebuffer (GPU/CPU)
↓
Экран
Text Engine: Для текста Flutter использует встроенный text engine, который:
- Парсит текст
- Выполняет shaping (как буквы взаимодействуют друг с другом)
- Рендерит глифы
// Когда вы напишите:
Text('مرحبا') // Арабский текст
// Под капотом происходит сложный процесс шейпинга для
// корректного отображения RTL текста
Animation System: Flutter имеет встроенную систему анимаций, работающую на C++ уровне:
// AnimationController работает в отдельном потоке
var controller = AnimationController(duration: Duration(seconds: 1));
// Каждый frame (60 fps) вызывает listener
controller.addListener(() {
setState(() {}); // Но это не реальный setState, это синхронизированный вызов
});
4. Platform Embedder
Этот слой связывает Dart/Engine с нативным кодом платформы.
Android:
Flutter Engine ↔ Android Embedder ↔ Android Framework
(C++)
- Flutter Engine встраивается в AndroidView или FlutterActivity
- Platform Channels позволяют общаться между Dart и Java/Kotlin
// Когда вы вызываете Platform Channel в Dart
const platform = MethodChannel('com.example.app/native');
await platform.invokeMethod('getBatteryLevel');
// Происходит:
// 1. Dart сериализует данные
// 2. Передаёт в C++ Engine
// 3. Engine вызывает нативный код (Kotlin/Java)
// 4. Нативный код вызывает Android API
// 5. Результат сериализуется и возвращается в Dart
iOS:
Flutter Engine ↔ iOS Embedder ↔ UIKit Framework
(C++)
Аналогично Android, но используется Objective-C/Swift и UIKit.
Web:
- Flutter для Web компилируется в JavaScript/WebAssembly
- Использует HTML Canvas для рендеринга
- Dart компилируется в JavaScript через dart2js
5. Система рендеринга в деталях
Vsync и Frame Pipeline:
Screen refresh (60 Hz или 120 Hz)
↓
BuildFrame (1000ms / 60fps = ~16ms)
├─ Animate (обновить animations)
├─ Build (вызвать build методы widgets)
├─ Layout (расчёт размеров и позиций)
├─ Paint (подготовить команды для Skia)
└─ Composite (объединить слои)
↓
Rasterize (Skia преобразует команды в пиксели)
↓
Present (отправить на экран)
Layer Tree и Compositing:
// Этот код создаёт несколько слоёв
Scaffold(
appBar: AppBar(), // Layer 1 (отдельный слой для app bar)
body: ListView(...), // Layer 2 (scrollable content)
floatingActionButton: ... // Layer 3 (отдельный слой для FAB)
)
// Flutter оптимизирует рендеринг через слои:
// - Если scroll, то Layer 2 перемещается, но Layer 1 и 3 не перерисовываются
6. Hot Reload (Developer Mode)
Это одна из самых крутых фишек Flutter, возможна благодаря JIT в dev mode:
1. Вы меняете код в IDE
2. IDE отправляет изменённый исходный код Dart VM
3. Dart VM перекомпилирует только изменённые классы
4. Виджеты перестраиваются с новым кодом
5. Состояние сохраняется (если поддерживается)
7. Memory Management
Dart Garbage Collector:
- Использует generational GC
- "Young" объекты (только что созданные) быстро удаляются
- "Old" объекты живут дольше
// Flutter автоматически управляет памятью
var users = <User>[]; // Создаём список
for (var i = 0; i < 1000; i++) {
users.add(User(name: 'User $i')); // GC следит за памятью
}
users.clear(); // Объекты User будут удалены GC'ом
Image Cache: Flutter кэширует изображения в памяти
// Flutter автоматически кэширует декодированные изображения
Image.network('https://...'); // Первый раз — долго
Image.network('https://...'); // Второй раз — из кэша
// Если нужно контролировать кэш
ImageCache cache = imageCache;
cache.maximumSize = 100;
cache.clear();
8. Compilation Process
Development (flutter run):
source.dart
↓ (Dart Frontend Compiler)
.dill (Kernel IR)
↓ (Dart VM)
Bytecode / JIT
↓
Execution with Hot Reload
Release (flutter build):
source.dart
↓ (Dart2Native AOT compiler)
machine code (ARM64/x86_64)
↓
Linked native executable
↓
.aar (Android) или .framework (iOS)
9. Event Loop и Threads
Flutter работает с несколькими потоками:
Platform Thread (Main/UI Thread)
├─ Dart Code execution
├─ Widget building
└─ Frame rendering
GPU Thread
└─ Skia rendering
IO Thread
└─ Network, file operations
// Даже хотя сам Dart single-threaded,
// Heavy операции идут в фоновых потоках
await http.get(...); // Выполняется на IO thread
await compute(heavy, ...) // Выполняется на отдельном isolate
10. Optimization Techniques Under the Hood
Const Constructor Optimization:
const Icon(Icons.add) // Объект создаётся один раз при compile time
// vs
Icon(Icons.add) // Объект создаётся каждый раз при runtime
RepaintBoundary для оптимизации:
RepaintBoundary(
child: ExpensiveWidget(), // Этот виджет в отдельном слое
);
// Если parent перестраивается, ExpensiveWidget не перерисовывается
Выводы
Flutter под капотом — это хорошо спроектированная архитектура, объединяющая:
- Dart VM для управления памятью и выполнением
- Skia для графики
- Platform embedders для нативной интеграции
- Умную систему Layer и Compositing для оптимальной производительности
Это объясняет, почему Flutter так быстр и универсален. Понимание этих слоёв помогает писать более эффективный код и отлаживать производительность.