Flutter
Flutter — це UI-фреймворк від Google, який малює кожен піксель застосунку власним рушієм з однієї кодової бази на Dart для iOS, Android, вебу й десктопа. Через цей вибір застосунок на Flutter виглядає однаково всюди й не змінюється, коли змінюється операційна система, — навіть коли вона змінюється навмисно, як це зробила iOS 26. Сторінка починається з шістнадцяти речей, які потрібні застосунку, і того, малює їх Flutter чи мусить просити платформу; далі — три дерева й бюджет кадру, ціна перебудови, Dart та ізоляти, межа з платформою й редизайни ОС, релізи до Flutter 3.47, п’ять задокументованих кейсів і те, де все це вироджується.
- Поточна версія
- Flutter 3.47 · серп. 2026 · Dart 3.13
- Модель
- Малює кожен піксель; решту просить в ОС
- Підтримка
- Реліз щокварталу; виправлення — лише для останнього
Що Flutter малює сам, а що мусить просити, — шістнадцять речей, потрібних застосунку
Нативний застосунок просить кнопку в операційної системи, і система її малює. Застосунок на Flutter не просить: він малює кнопку сам на полотні, яке йому видала система, і система так і не дізнається, що там кнопка. Це одне рішення розкладає все, що потрібно застосунку, на кілька видів. Щось Flutter малює. До чогось дістає через міст, який сам підтримує. Щось — нативний код у плагіні, написаний кимось іншим. А чогось не може взагалі. Вид визначає, що станеться того дня, коли зміниться операційна система, — а це головне питання для застосунку, що живе роками. Ось шістнадцять речей, потрібних застосунку. Наступні розділи посилаються на рядки за номерами.
| # | Що потрібно застосунку | Хто це дає | Коли це змінює ОС | Перевірка |
|---|---|---|---|---|
| 1 | Кнопки, списки, діалоги, панелі вкладок і навігації | Малює Flutter — віджети Material і Cupertino, з серпня 2026 року пакети material_ui і cupertino_ui | Нічого не змінюється: Liquid Glass з iOS 26 до Flutter-застосунків не дійшов | Вирішіть, якого дизайну дотримуєтеся, і закладайте наступний редизайн самі |
| 2 | Фізика скролу й overscroll | Flutter, що імітує кожну платформу: відскок на iOS, розтягування на Android | Змінюється, лише коли зміну скопіює Flutter | Порівнюйте обидві платформи поруч: фізика тепер — ваше дизайнерське рішення |
| 3 | Розкладка й малювання тексту | Власний текстовий рушій Flutter зі шрифтами платформи | Однаково на кожному пристрої; системні зміни тексту самі не застосовуються | Перевіряйте довгі українські слова, письмо справа наліво, тайські рядки й великий масштаб тексту |
| 4 | Переходи між сторінками й жест «назад» | Перехід малює Flutter; predictive back на Android має реалізувати фреймворк | Android 16 (API 36) вмикає predictive back типово | PopScope замість застарілого WillPopScope; перевірте «назад» на Android 16 |
| 5 | Саме малювання | Рушій Flutter, Impeller, на Metal чи Vulkan, з OpenGL ES як запасним шляхом на Android | Помилка драйвера GPU на одній моделі Android стає вашою помилкою | Тестуйте на слабкому Android: нижче API 29 чи без Vulkan працює запасний шлях |
| 6 | Введення тексту й клавіатура | Клавіатура платформи, з’єднана з полями Flutter через канал введення тексту | Нові можливості клавіатури приходять, коли їх під’єднає Flutter | Перевіряйте автовиправлення, українське й CJK-введення на реальних пристроях |
| 7 | Доступність — VoiceOver, TalkBack | Дерево семантики, яке будує Flutter і перекладає в API доступності платформи | Настільки добре, наскільки добрі ваші мітки Semantics; у власних віджетів їх типово немає | Пройдіть кожен сценарій із читачем екрана на обох платформах |
| 8 | Автозаповнення й менеджери паролів | Під’єднано до сервісу автозаповнення платформи | Працює для полів, що оголошують, що в них | autofillHints на кожному полі входу й адреси |
| 9 | Безпечні зони, виріз, системні панелі | ОС повідомляє відступи; Flutter розкладає довкола них | Android 16 робить edge-to-edge обов’язковим | SafeArea чи відступи з MediaQuery на кожному екрані; перевірте жестову й трикнопкову навігацію |
| 10 | Камера, біометрія, Bluetooth, файли, геолокація | Плагіни: Dart-API поверх коду на Swift і Kotlin | Нове правило дозволів ламає плагін, доки супровідник не випустить виправлення | Перш ніж брати плагін, перевірте видавця, останній реліз і відкриті issues |
| 11 | Пуш-сповіщення й фонова робота | Плагіни плюс налаштування нативних проєктів; коли фоновий код може працювати, вирішує ОС | Найкрихкіша категорія на кожному релізі ОС | Перевіряйте з убитим застосунком, на обох платформах, після кожного оновлення ОС |
| 12 | Мапи, вебв’ю, відеоплеєри, нативна реклама | Platform views: нативна в’ю, вбудована в зображення Flutter | Поводиться нативно, але її композиція коштує кадрів, а жести можуть застрягати на стику | Кілька на екран; перевіряйте скрол над ними й довкола |
| 13 | Покупки в застосунку й підписки | Плагіни поверх StoreKit і Google Play Billing | Платіжні бібліотеки магазинів мають власні дедлайни | Тримайте платіжний плагін свіжим: від нього залежить дохід |
| 14 | Віджети домашнього екрана, застосунки для годинника, Live Activities, App Intents | Лише нативний код — Flutter там не малює | Кожен реліз ОС додає поверхні, до яких Flutter не дістає | Закладайте нативні навички під це від початку |
| 15 | Іконка, екран запуску, тексти дозволів, підпис, життєвий цикл | Нативні проєкти ios/ та android/ усередині проєкту Flutter | Сюди приходять правила магазинів — життєвий цикл UIScene, target API | Переглядайте нативні проєкти на кожному оновленні Flutter; 3.38 додав міграцію на UIScene |
| 16 | Системний інтерфейс — клавіатура, «Поділитися», запити дозволів | ОС, яку викликає Flutter | Змінюється разом з ОС, як у будь-якому застосунку | Нічого — межа між рядками 1 і 16 і є темою цієї сторінки |
Три дерева, два потоки й бюджет кадру
Коли ви пишете кнопку у Flutter, не створюється ні UIButton, ні Android-Button. Flutter будує власне дерево, сам робить розкладку й віддає результат своєму рушію, який перетворює його на команди малювання для GPUGraphics Processing Unit — процесор для паралельних обчисленьПроцесор із тисяч простих ядер, які роблять однакову операцію над великими масивами чисел одночасно. Саме така будова потрібна для тренування й запуску моделей — тому GPU давно перестали стосуватися лише графіки.Усі терміни. Платформа дає поверхню для малювання, події введення — і майже нічого більше. Це і є той єдиний факт, що пояснює про фреймворк майже все інше, зокрема рядок 1.
Конвеєр проходить через три дерева, і розуміння, що є що, робить поведінку фреймворку зрозумілою. Віджети — ваш опис екрана: незмінні, дешеві, їх постійно викидають і будують знову. Елементи — те, що справді змонтовано; вони переживають перебудови й тримають стан, тому віджет можна перестворювати шістдесят разів на секунду, не втрачаючи його. Об’єкти рендерингу роблять розкладку й малювання. Саме вони дорогі, тож Flutter перевикористовує об’єкт рендерингу щоразу, коли новий віджет має той самий тип і ключ, що й старий.
Рушій — Impeller, що замінив Skia через одну конкретну проблему. Skia компілював шейдери GPU — маленькі програми, що малюють кожен ефект, — тоді, коли ефект з’являвся вперше, на телефоні користувача. Перша анімація могла застрягти на десятки мілісекунд, поки шейдер компілювався, — і так після кожного встановлення застосунку; розділ кейсів розповідає цю історію. Impeller компілює всі свої шейдери під час збірки рушія, тож під час роботи нічого не компілюється. Він став типовим на iOS у Flutter 3.10 (травень 2023) і єдиним рендерером там у 3.29; типовим на Android від APIApplication Programming Interface — контракт між програмамиПравила, за якими одна програма звертається до іншої: які запити можна надіслати, у якому вигляді й що прийде у відповідь. Для того, хто звертається, це контракт — усе, що за ним, лишається чорною скринькою, і саме тому другий бік можна переписати, не зламавши вас.Докладніше в статті →Усі терміни 29 у 3.27 (грудень 2024), з OpenGL ES як запасним шляхом на старіших пристроях чи без Vulkan; і типовим на десктопі в 3.47. Flutter у вебі досі малює через Skia, скомпільований у WebAssembly.
Роботу кожного кадру роблять два потоки. UIUser Interface — те, що бачить користувачУсе, що користувач бачить і чим керує: екрани, кнопки, поля, стани. UI відповідає за те, ЯК виглядає взаємодія; чи має вона сенс узагалі — це вже питання UX, і ці два поняття плутають постійно.Усі терміни-потік виконує весь код на Dart — ваш і фреймворку — і створює опис кадру, що зветься деревом шарів. Потік растру перетворює його на команди GPU. При 60 Гц разом вони мають 16,7 мс на кадр; при 120 Гц — 8,3 мс. З Flutter 3.29 UI-потік на iOS і Android — узагалі не окремий потік: Dart виконується в головному потоці платформи (десктоп приєднався в 3.35). Це дозволяє Dart викликати API платформи синхронно через FFI. А ще це означає, що довга задача на Dart тепер затримує й код плагінів та системні колбеки, а не лише ваші кадри.
Оверлей продуктивності й Flutter DevTools показують обидва потоки стовпчиками відносно лінії 16 мс, і колір підказує, яка у вас проблема. Червоний стовпчик в UI-потоці означає, що Dart робить забагато: великий build, розбір, сортування — робота, якій місце в ізоляті. Червоний стовпчик у потоці растру означає, що кадр задорогий для малювання: шари, які зберігають і відновлюють ефекти на кшталт прозорості, обрізання й розмиття, завеликі зображення, тіні на кожному рядку списку. Виправлення в них різні, тож спершу подивіться, а потім оптимізуйте.
Перебудови: що насправді перемальовує один setState
setState робить одне: позначає віджет, що володіє станом, як «брудний», і в наступному кадрі Flutter знову викликає його метод build і проходить усе, що той повертає. Віджети дешеві, тож перебудова зазвичай не є проблемою. Коштує інше: скільки всього лежить під віджетом, чий стан змінився, і скільки роботи робить кожен build дорогою. Лічильник, чий стан живе вгорі екрана, перебудовує екран; той самий лічильник у власному маленькому віджеті перебудовує два віджети.
- Опускайте стан до найменшого віджета, якому він потрібен, і піднімайте лише тоді, коли він справді потрібен другому місцю.
- Виносьте частини екрана в класи віджетів, а не в методи, що повертають віджети: клас отримує власний елемент і може бути пропущений; метод виконується знову разом із батьком.
- Ставте
const-конструктори всюди, де аргументи сталі:const-віджет — той самий об’єкт у кожній перебудові, тож Flutter на ньому зупиняється. - Тримайте
buildвільним від роботи: жодного розбору, сортування, створення контролерів чи потоків —buildможе виконуватися шістдесят разів на секунду. - Давайте елементам списку
Key, якщо їх можуть переставляти, вставляти чи видаляти, інакше стан лишиться за позицією, а не за елементом. - Обгортайте частину, що часто перемальовується, — анімацію, індикатор прогресу — у
RepaintBoundary, щоб її малювання не перемальовувало сусідів.
Керування станом і чесна відповідь
У Flutter немає офіційної бібліотеки керування станом — тому кожна розмова про це перетворюється на порівняння пакетів. Корисно дивитися на поле за тим, скільки структури нав’язує кожен варіант, і правильна відповідь залежить більше від розміру команди, ніж від переваг бібліотеки.
setState
Вбудований, локальний для одного віджета. Правильний для всього, чим володіє один екран, і хибний тієї миті, коли двом екранам потрібне те саме значення.
Provider / Riverpod
Впровадження залежностей плюс спостережуваний стан. Riverpod новіший із двох: перевіряється під час компіляції, тестований і незалежний від дерева віджетів.
BLoC
Події всередину, стани назовні, потоками. Забагато церемонії для малого застосунку; передбачувано й простежувано для великої команди на довгому проєкті.
Порада, що тримається незалежно від вибору, — це правило перебудов вище, застосоване до стану: тримайте його якомога ближче до місця використання й виносьте назовні лише тоді, коли він справді потрібен другому місцю. Більшість складності, яку приписують керуванню станом у Flutter, створено власноруч: глобальне сховище, заведене першого ж дня для застосунку з чотирьох екранів без спільного стану, яке потім на кожну зміну перебудовує більше, ніж треба.
Dart: два компілятори, ізоляти й генерація коду
Вивчати мову заради фреймворку звучить як витрата, і Dart — приблизно найменша версія цієї витрати: будь-хто, кому зручно з TypeScriptJavaScript із перевіркою типівJavaScript плюс опис того, що саме функція приймає й повертає, — і цей опис перевіряється в редакторі ще до запуску. У браузер він не потрапляє: перед складанням його компілюють назад у звичайний JavaScript, тож типи — це інструмент розробки, і не більше.Докладніше в статті →Усі терміни, Java чи C#, читає його першого ж вечора. Він статично типізований і надійний щодо null: значення, що може бути null, не можна використати як таке, що не може, і компілятор це забезпечує; від Dart 3 іншого режиму немає. Незвичайним Dart робить те, що він компілюється двома способами під дві цілі. У розробці він працює на віртуальній машині з JIT-компілятором — саме це уможливлює гаряче перезавантаження зі збереженням стану: змінили віджет — і запущений застосунок оновився менш ніж за секунду, не втративши місця. Для релізу він компілюється заздалегідь у машинний код, тож у поставленому застосунку немає інтерпретатора. Швидкість розробки й продуктивність релізу зазвичай торгуються одна проти одної; тут — ні.
Гаряче перезавантаження має межі, які варто знати, перш ніж вони коштуватимуть пів дня. Воно вставляє змінений код і перебудовує дерево віджетів, але не виконує знову main() чи initState об’єкта стану й зберігає поточні значення глобальних і статичних змінних. Зміна будь-чого з цього потребує гарячого перезапуску, що скидає стан застосунку. Зміна нативного коду — плагіна, проєктів ios/ чи android/ — потребує повної перезбірки, бо гаряче перезавантаження дістає лише до Dart.
Паралельність працює як у JavaScript: кожен ізолят має один потік і цикл подій, тож await ніколи не блокує екран, а довге обчислення — блокує. Для важкої роботи ви запускаєте ще один ізолят із власною пам’яттю, що спілкується з вашим лише повідомленнями, — без спільного стану, а отже, без гонок, які приносять потоки. Isolate.run робить це одним рядком: виконує функцію в новому ізоляті й повертає результат. Декодування великої JSONJavaScript Object Notation — текстовий формат данихТекстовий формат для передавання даних: пари «ключ — значення», списки, числа й рядки. Він народився в JavaScript, але сьогодні його читає будь-яка мова — і саме тому ним відповідає більшість API, а не чимось потужнішим.Усі терміни-відповіді, зміна розміру зображення чи розбір файлу — саме туди, як показує схема бюджету кадру вище.
| Dart | Вихід | Що змінилося у вигляді коду |
|---|---|---|
| 3.0 | трав. 2023 | Лише надійна null-безпека; записи, патерни, sealed-класи й модифікатори класів |
| 3.10 | листоп. 2025 | Крапкові скорочення: .center там, де тип уже відомий |
| 3.12 | трав. 2026 | Приватні іменовані параметри |
| 3.13 | серп. 2026 | Первинні конструктори — поля, оголошені в заголовку класу |
Чого в Dart досі немає, то це вбудованого способу згенерувати toJson, copyWith і рівність для класу даних. Команди пишуть їх генерацією коду: build_runner запускає пакети на кшталт freezed і json_serializable, що пишуть файли .g.dart поруч із вихідним кодом. Макроси мали це замінити — і їх скасували в січні 2025 року; розділ кейсів пояснює чому. Первинні конструктори в 3.13 — перша з менших можливостей, обіцяних натомість, і вони прибирають частину шаблонного коду, не прибираючи генератора.
Межа з платформою: канали, FFI, плагіни й редизайни ОС
Те, чого Flutter не може намалювати, він мусить попросити, і перейти на той бік можна чотирма способами. Плагін — це просто пакет, що користується одним із них і постачає вам нативну половину.
| Спосіб | Як викликає | Для чого |
|---|---|---|
Канал платформи (MethodChannel) | Асинхронне повідомлення коду на Swift чи Kotlin | Більшість викликів плагінів; усе, що може зачекати кадр |
| Pigeon | Згенерований типізований код каналу з обох боків | Ваш власний нативний код без рукописних рядків-повідомлень |
FFI (dart:ffi, з ffigen і jnigen) | Прямий синхронний виклик | Бібліотеки C, а з 3.29 — і API платформи, що мають працювати в головному потоці |
| Platform view | Ціла нативна в’ю, вкомпонована в зображення Flutter | Мапи, вебв’ю, відеоплеєри, нативна реклама (рядок 12) |
Через рядки 10–15 плагіни — частина застосунку на Flutter, найбільш відкрита до часу. Кожен — це нативний код для двох платформ, що змінюються щороку, і підтримує його той, хто опублікував. Коли Apple оголосила, що застосунки, зібрані з iOS 27 SDKSoftware Development Kit — готовий набір для платформиЗібраний набір бібліотек, інструментів і прикладів для роботи з чужою платформою. Відмінність від API в тому, що API лише описує правила, а SDK дає код, який уже вміє за цими правилами говорити.Усі терміни, мусять використовувати життєвий цикл на сценах, інакше не запустяться, сам Flutter додав міграцію в 3.38 — а потім запити на підтримку UIScene відкрилися в одному популярному плагіні за іншим. Перш ніж додати плагін, перевірте, хто його видає, коли був останній реліз, які платформи він підтримує і скільки чекають його відкриті issues. Після додавання для ваших користувачів це ваш код.
Коли операційна система перемальовує себе
iOS 26, що вийшла у вересні 2025 року, перемалювала системні елементи керування в напівпрозорому стилі, який Apple називає Liquid Glass. Будь-який застосунок, перезібраний з iOS 26 SDK — без цього з 28 квітня 2026 року не приймають завантажень в App Store, — отримує новий вигляд усюди, де елемент малює операційна система. Саме це точно проводить межу між підходами. Застосунок на SwiftUI чи UIKit змінився майже всюди. Застосунок на React Native — усюди, де його компоненти є справжніми в’ю платформи. Застосунок на Flutter — лише в системному інтерфейсі, який він викликає, бо його Cupertino-віджети — це малюнки елементів керування iOS 18, а не самі елементи.
Команда Flutter написала у своєму трекері в червні 2025 року, що «зараз не розробляє нові дизайнерські можливості Apple’26 у бібліотеці Cupertino». Відповідь прийшла в серпні 2026 року: Material і Cupertino опублікували як окремі пакети material_ui і cupertino_ui — копії всередині фреймворку мають застаріти й зникнути, — щоб оновлення дизайну виходили щотижня, а не з кожним квартальним релізом, і в оголошенні сказано, що «робота над офіційними реалізаціями Liquid Glass уже триває». Для нативних застосунків годинник іде у зворотний бік. Apple дала їм зберегти старий вигляд ключем у Info.plist, UIDesignRequiresCompatibility, і її документація тепер каже, що для застосунків, зібраних з iOS 27 SDK, цей ключ ігнорується. Тож упродовж року нативні застосунки не зможуть уникнути нового дизайну, а застосунки на Flutter зберігатимуть старий, доки хтось його не перебудує.
Релізи, підтримка і який Flutter перед вами
Flutter випускає стабільний реліз щокварталу — у лютому, травні, серпні й листопаді, — і номер версії щоразу росте на три: 3.41, 3.44, 3.47. Кожен іде в парі з релізом Dart. Між ними виправлення отримує лише поточний стабільний: 3.47.6 вийшов 1 жовтня 2026 року, а 3.44 відтоді, як вийшов 3.47, не отримав жодного. Гілки довгострокової підтримки немає, тож «підтримуваний» означає «останній», а команда, що пропускає рік, опиняється на чотири релізи позаду.
| Flutter | Вихід | Що змінилося |
|---|---|---|
| 3.10 | трав. 2023 | Dart 3; Impeller типовий на iOS |
| 3.16 | листоп. 2023 | Material 3 типово |
| 3.22 | трав. 2024 | WebAssembly для Flutter web — стабільно; MaterialState перейменовано на WidgetState |
| 3.27 | груд. 2024 | Impeller типовий на Android від API 29; широка колірна гама, withOpacity застарів |
| 3.29 | лют. 2025 | UI-потік і потік платформи злито на iOS і Android; Skia прибрано з iOS; HTML-рендерер для вебу прибрано |
| 3.35 | серп. 2025 | Потоки злито на macOS і Windows |
| 3.38 | листоп. 2025 | Dart 3.10; підтримка iOS 26 і Xcode 26; міграція на життєвий цикл UIScene |
| 3.47 | серп. 2026 | Dart 3.13; Material і Cupertino — окремі пакети; Impeller типовий на десктопі; Widget Previewer стабільний |
Який Flutter перед вами
| Що ви бачите в коді | Що це означає |
|---|---|
WillPopScope | Написано до predictive back; застаріло на користь PopScope — рядок 4 |
useMaterial3: false або відсутній useMaterial3 у коді 2023 року | Стилі Material 2; типове значення змінилося в 3.16 |
MaterialStateProperty | Старше за 3.22, де воно стало WidgetStateProperty |
color.withOpacity(0.5) | Старше за 3.27; withValues(alpha: 0.5) зберігає точність широкої гами |
--web-renderer html у скрипті збірки | HTML-рендерер і сам прапорець прибрано в 3.29; скрипт збірки треба оновити |
Файли розігріву SkSL (--bundle-sksl-path) | Обхід ривків через шейдери з часів Skia; під Impeller не має сенсу |
import 'package:flutter/material.dart' після серпня 2026 | Поки що працює — копії у фреймворку мають застаріти й зникнути; dart fix переносить імпорти на material_ui, де будують Liquid Glass і Material 3 Expressive |
iOS-AppDelegate без делегата сцен | Шаблон, старший за 3.38; змінити обов’язково до збірки з iOS 27 SDK |
Дедлайни магазинів щодо збірок стосуються Flutter так само, як будь-якого іншого застосунку, — сторінка про React Native зводить їх у таблицю: iOS 26 SDK з квітня 2026 року, життєвий цикл UIScene з iOS 27 SDK, Android 16 як target API з 31 серпня 2026 року й сторінки пам’яті по 16 КБ для кожної нативної бібліотеки. У Flutter рушій виконує свою частину, коли ви оновлюєтеся; нативні проєкти (рядок 15) і кожен плагін (рядки 10–14) мусять виконати свою.
П’ять кейсів і те, чого в кожному бракувало
Кейси взято з трекера issues і блогів самого Flutter, вітрини Google і публічних записів спільноти. Разом вони покривають рендерер, велике переписування, людей за фреймворком, можливість мови, що так і не вийшла, і платформу, що перемальовує сама себе.
| Кейс | Що сталося | Чого бракувало |
|---|---|---|
| Ривки через шейдери, 2019–2025 | Перші анімації смикалися, поки Skia компілював шейдери на телефоні; обхідний розігрів був крихким | Шейдери, скомпільовані до постачання, — Impeller |
| Google Pay, 2020 | Два нативні застосунки, 1,7 мільйона рядків, переписано в один Flutter-застосунок, на 35% менший | Нічого — переписування цілого застосунку командою, яку для цього навчили |
| Flock, жовт. 2024 | Колишній інженер Flutter форкнув фреймворк, пославшись на малу заморожену команду | Погляд на людей за фреймворком як на ризик залежності |
| Макроси Dart, січ. 2025 | Показану в прев’ю можливість мови скасували, бо вона сповільнювала редактор і гаряче перезавантаження | Правило не будувати на можливості, яка ще не вийшла |
| Liquid Glass, черв. 2025 – 2026 | iOS перемалювала свої елементи керування; нативні застосунки змінилися після перезбирання, Flutter-застосунки — ні | План, що називає редизайн роботою самої команди |
Перший кейс — сам рендерер. Skia, графічна бібліотека, якою Flutter користувався від початку, компілював кожен шейдер GPU тоді, коли застосунок уперше його потребував, — на телефоні користувача, посеред кадру. Коли перехід між сторінками чи розмиття запускалися вперше, кадр міг застрягти на десятки мілісекунд; удруге все йшло плавно. Користувачі бачили застосунок, що смикається, поки новий, — особливо на iOS, де не було постійного кешу шейдерів. Issue #32170, відкритий 6 травня 2019 року, просив автоматичного виправлення. Тимчасовою відповіддю, з Flutter 1.20 у 2020 році, було запустити застосунок, зібрати використані шейдери у файл і вкласти цей файл у збірку — що покривало лише ті шляхи, які хтось не забув пройти, і могло відрізнятися від пристрою до пристрою. Справжнім виправленням став інший рушій: Impeller компілює кожен шейдер під час збірки рушія. Він став типовим на iOS у 3.10 (травень 2023), на Android — у 3.27 (грудень 2024), а Skia прибрали з iOS у 3.29. Шість років від звіту до видалення — ціна проблеми, що жила в архітектурі, а не в окремому застосунку.
Третій кейс — про людей. У жовтні 2024 року Метт Керролл, який працював над Flutter у Google, оголосив Flock — форк, що мав іти в ногу з Flutter, але швидше приймати виправлення й можливості. Його причини були публічними й конкретними: за його підрахунком, близько 50 людей у Google будували фреймворк, яким користується приблизно мільйон розробників, кількість посад було заморожено приблизно з 2023 року, у 2024 році були скорочення, а три з шести платформ Flutter фактично перебували в режимі підтримки. Відтоді Flutter виходив щокварталу, тож форк не передбачив краху. Він показав залежність, якої більшість команд ніколи не записує: фреймворк — це ще й команда, що його підтримує, а її розмір і пріоритети визначає бюджет однієї компанії. Запишіть, що ви робитимете, якщо фреймворк сповільниться: які частини застосунку зможете зберегти і які плагіни зможете підтримувати самі.
Четвертий кейс — можливість, яку пообіцяли, показали й відкликали. Макроси Dart — код, що пише код усередині компілятора, щоб клас даних отримував toJson і рівність без генератора, — показали з прев’ю JsonCodable на Google I/O у травні 2024 року. 29 січня 2025 року Віджай Менон оголосив, що команда Dart зупинилася: реалізація сповільнювала редагування (аналіз і автодоповнення) і сповільнювала інкрементну компіляцію — перший крок гарячого перезавантаження, — а команда не була певна, що виправить обидва за розумний час. Натомість пообіцяли три менші речі: augmentations, швидший build_runner і окремі можливості мови для даних. До Dart 3.13 у серпні 2026 року вийшли первинні конструктори; augmentations у стабільному релізі так і не з’явилися. Команди, що відклали генерацію коду в очікуванні макросів, повернулися до неї. Плануйте на тому, що вже вийшло.
Де він вироджується
Flutter щедрий до всього, що малює, і мовчазний щодо всього, чого не малює. Екран швидко будувати, і він однаковий усюди, тож команда може зайти далеко, перш ніж зустріне нативний бік, — і тоді зустрічає його весь одразу. Майже кожен збій — одне з цього:
- Метод
buildна сотні рядків зі станом угорі, що перебудовує цілий екран через одне значення. - Віджети, винесені в методи-помічники, а не в класи, тож
constніколи не зможе їх пропустити. - Розбір, декодування й сортування в UI-потоці — який із 3.29 ще й головний потік платформи.
- Продуктивність, оцінена в debug-режимі чи на емуляторі, а не в profile-режимі на телефоні середнього класу.
- Плагіни, взяті без перевірки, хто їх підтримує, що потім блокують дедлайн ОС (рядки 10–15).
- Власні віджети без
Semantics, невидимі для читача екрана (рядок 7). - Вигляд Cupertino, обраний, щоб «відчуватися нативно», і залишений позаду наступним редизайном платформи (рядок 1).
- Версія Flutter річної давнини із застарілими API з таблиці «який Flutter» на своїх місцях.
- Пакет глобального стану, узятий першого дня для застосунку, у якого спільного стану немає.
- Flutter web, обраний для публічного текстового сайту, де полотно — хибний вихід для виділення тексту, пошукових систем і доступності.
Чесна межа — лінія між рядком 1 і рядком 16. Flutter володіє кожним пікселем, який малює, тож не може успадкувати нічого, що платформа додає до своїх елементів керування — редизайн, нову взаємодію, поведінку доступності, — доки хтось це не перереалізує. Застосунок, що має відчуватися точно як платформа, платить цю ціну на кожному великому релізі ОС, а застосунок, чия цінність живе у віджетах, циферблатах годинника й системних інтеграціях, однаково пише більшість цієї цінності нативно. Рушій їде всередині застосунку, тож бінарник Flutter стартує на кілька мегабайтів більшим за нативний. Для брендових продуктів з одним дизайном на всіх платформах, інтерфейсів, насичених анімацією, і команд без наявних навичок React обмін працює навпаки, і Google Pay — масштаб, на якому це доведено.
Практична перевірка займає десять хвилин. Запустіть flutter --version і знайдіть реліз у таблиці. Знайдіть у коді WillPopScope, withOpacity і MaterialStateProperty. Складіть список плагінів із pubspec.yaml з видавцем і датою останнього релізу кожного. Відкрийте найповільніший екран у profile-режимі на телефоні середнього класу з Android з увімкненим оверлеєм продуктивності й запишіть, який стовпчик червоніє. Увімкніть VoiceOver і TalkBack і пройдіть головний сценарій. І переконайтеся, що в iOS-проєкті є делегат сцен, перш ніж хтось збиратиме з iOS 27 SDK.
Коли це застосовувати
Застосовуйте, коли
- Продукти, що мають виглядати й поводитися однаково на кожній платформі — з однієї специфікації дизайну.
- Брендові інтерфейси з власною дизайн-системою, де ви й так збиралися перевизначати віджети платформи.
- Насичений анімаціями інтерфейс — володіння конвеєром малювання тут саме й дає перевагу.
- Команди без наявних навичок React, для яких Dart не більша перешкода, ніж будь-який інший новий стек.
Уникайте, коли
- Застосунки, що мають відчуватися точно як платформа й іти за її редизайнами, — там суть в успадкованих нативних елементах.
- Продукти, чия цінність живе у віджетах, застосунках для годинника й системних інтеграціях, які однаково пишуть нативно.
- Публічні текстові сайти — рендер у полотно є хибним інструментом для тексту, пошуку й доступності.
- Усе, що збудовано навколо найновішого API платформи, — до Flutter воно доходить після того, як дійшло до нативного коду.
Джерела й метод
На чому стоїть ця стаття
- 13 джерел
- Перевірено 13 жовтня 2026 р.
Практики й походження термінів
що малює Flutter, потоки, рендерер і версії- ДокументаціяFlutter architectural overview (відкривається в новій вкладці)docs.flutter.dev
- ДокументаціяImpeller rendering engine (відкривається в новій вкладці)docs.flutter.dev
- ДокументаціяFlutter performance profiling (відкривається в новій вкладці)docs.flutter.dev
- ДокументаціяFlutter FAQ (відкривається в новій вкладці)docs.flutter.dev
- СтаттяMaterial and Cupertino decoupling are here (відкривається в новій вкладці)Flutter Blog · 09.09.2026
- ДокументаціяFlutter releases (releases_linux.json) (відкривається в новій вкладці)Google Cloud Storage · flutter_infra_release
- Документаціяdart-lang/sdk — CHANGELOG (відкривається в новій вкладці)GitHub
Кейси
розділ «П’ять кейсів і те, чого в кожному бракувало»- ДокументаціяAutomatic/scalable shader warm-up — flutter/flutter #32170 (відкривається в новій вкладці)GitHub · 06.05.2019
- СтаттяGoogle Pay — Flutter showcase (відкривається в новій вкладці)flutter.dev
- СтаттяMatt Carroll — We’re forking Flutter. This is why.Flutter Foundation · 27.10.2024
- СтаттяFlutter forked as Flock, developer cites ‘company-wide issues at Google’ (відкривається в новій вкладці)devclass · 30.10.2024
- СтаттяVijay Menon — An update on Dart macros & data serialization (відкривається в новій вкладці)Dart · 29.01.2025
- ДокументаціяSupport for iOS 26 “Liquid Glass” Design in Cupertino Widgets — flutter/flutter #170310 (відкривається в новій вкладці)GitHub · 10.06.2025
Дослідження з Claude. Пошук і звірку першоджерел зроблено з Claude (Anthropic). Відбір, текст і перевірку фактів — редакція Anatomy of IT Product.
Було корисно?
Поділіться з тим, хто працює над тією ж задачею.