Чи варто інвестувати у Flutter. Порівняння Flutter і React Native

Давайте поговоримо про кроссплатформної мобільного розробці, бо привід є! Не так давно, а саме в грудні 2018 року, на заході від Google нам завезли ще один фреймворк» — Flutter. Сьогодні ми подивимося на Flutter з різних сторін: історію, архітектуру, переваги, недоліки, а також порівняємо його з React Native.

Історія виникнення

На початку варто розповісти про передумови та історію виникнення Flutter. Все почалося ще в 2014 році. У гонитві за швидкістю, команда Google Chrome експериментувала з рендерингом вмісту сторінок. Метою експерименту була перевірка: чи можна прискорити рендеринг, якщо відмовитися від традиційної моделі лейаута, попутно позбувшись від вантажу зворотної сумісності, що накопичилася за багато років існування веба.

Основою для експериментів став движок Blink, а результатом — приріст продуктивності в 20 разів за рахунок наступних змін:

  1. Простий набір обмежень, що впливають на положення елемента на екрані (Box Model) — мінімальна і максимальна ширина і висота.
  2. Замість великого набору правил, який може бути застосований до будь-якого елементу, кожен компонент визначає свою просту лейаут-модель (центрування, паддінґ, колонка).

Мала кількість правил дозволяє істотно оптимізувати лейаут на рівні компонента. А проста модель обмежень, поширювана від батька вниз по дереву, дозволила домогтися лінійної залежності між кількістю елементів в дереві і часом лейаута. Все відбувається настільки швидко, що Flutter не поділяє «створення» та «модифікацію» нсд. Замість цього, у разі змін батьківського віджета, він инвалидирует всі піддерево.

Результат цього експерименту було взято за основу при розробці Flutter.

Звідки взявся Dart

Спочатку Flutter був сумішшю З++ (частина движка Blink) + JavaScript, який використовувався як основну мову для написання коду. Але у розробників виникли проблеми з JS. Вирішили пошукати іншу мову йому на заміну. Команда досліджувала більше десятка мов і вибрала Dart як найбільш підходящий. Основними перевагами Dart є:

  1. АОТ-компіляція. В результаті маємо АРМ або х86 код з високою швидкодією на пристрої користувача.
  2. JIT-компіляція. Дає можливість запускати проект у віртуальній машині на емуляторі і реалізувати hot reload тривалістю менше однієї секунди із збереженням стану програми.
  3. Сувора система типів. Дозволяє забути про вибір між TS і Flow.
  4. Tree shaking compiler. При складанні програми видаляє весь невикористаний код.
  5. Generational garbage collection. Швидке виділення і очищення пам'яті.

Компоненти фреймворку


Flutter складається з трьох шарів: Embeder, Engine і Framework.

  1. Embeder. Платформозависимый код, що відповідає за взаємодію та запуск на кінцевій платформі.
  2. Engine. Написаний на С/С++, і включає в себе Dart як рівень абстракції для роботи з CPU, Skia — 2D бібліотеку для малювання та підсистему для візуалізації тексту, позичену у Android.
  3. Framework. Найбільша частина, повністю написана на Dart. Поділ на верстви дозволяє легко побудувати програми будь-якої складності. Можна використовувати готові віджети з Material-UI або реалізувати специфічні компоненти на основі базових віджетів. Є можливість гнучко працювати з анімацією і обробкою жестів. Таким чином, можна комбінувати швидку роботу з високорівневими віджетами з можливістю внесення/перевизначення більш глибоких шарів.

Архітектура


Особливістю архітектури Flutter є те, що він сам малює кожен піксель, контролює жести і анімацію. Він не використовує ОЕМ-віджети, як це робить React Native. Замість цього, команда Flutter створила два набору віджетів для основних мобільних платформ: Material для Android і Cupertino для iOS. Таким чином, вони заново відмалювали всі UI-компоненти з обох мобільних платформ, повністю повторивши їх поведінку. Безпосередньо з мобільною платформою (геолокація, звук, bluetooth) взаємодія відбувається через Platform Channels.

Фокус на споживача

У процесі створення Flutter, була проведена велика робота з виявлення основних больових точок при розробці мобільних додатків. Команда Flutter консультувалася з колегами з нативної і кроссплатформної розробці і зосередилася на наступних проблемах:

Slow development. Повільний цикл розробки з-за необхідності кожен раз компілювати додаток при внесенні змін. Додатковим незручністю є скидання стану програми. Припустимо, проблема знаходиться на третьому кроці майстра. При спробі виправити її, потрібно на кожне зміна в коді або заново проходити всі попередні кроки, або з допомогою хитрощів зробити так, щоб виконувати цю програму з потрібного місця.

Cross-platform look and feel. При розробці бувають випадки, коли додаток повинен виглядати однаково на обох платформах. Враховуючи особливості платформ, іноді цього досить складно домогтися.

Platform diversity. Різноманітність вендорів, які роблять пристрої на платформі Android, буває, позначається несподіваним чином на те, як виглядає і працює мобільний додаток.

Дві команди. При розробці окремих додатків для iOS і Android, доводиться утримувати дві команди, які розробляють одні і ті ж функції. А також є необхідність синхронізувати релізи при введенні в дію мажорних оновлень, щоб користувачі одній з платформ не були ущемлені в функціоналі.

Polishing. При кроссплатформної розробці, окремим процесом варто згадати полірування верстки, яка, наприклад, на iOS виглядає добре, а на Android містить вади. І навпаки.

Performance. Продуктивність підсумкового рішення при кроссплатформної розробці іноді залишає бажати кращого. Ті ж Cordova і React Native можуть доставити чимало головного болю.

У підсумку нам пропонують:

Fast development cycles. Оновлення програми з повним збереженням стану в емуляторі займає менше секунди (у більшості випадків).

Up to 120 FPS. Розробники заявляють про готовність платформи рендери на швидкості до 120 кадрів в секунду.

Pixel perfect rendering. Flutter завідує всім на екрані. Рендерингом кожного пікселя, анімацією, обробкою жестів. Це дозволяє домогтися максимальної подібності в роботі на різних платформах і мінімізувати вплив платформи на підсумковий зовнішній вигляд програми.

Rich set of customizable widgets. Разом з фреймворком поставляється готовий набір легко каталізуються віджетів, який покриває всі гайдлайны Material-UI і реалізує набір специфічних для iOS віджетів.

Supports iOS, Android, Веб, Desktop. Фактично, архітектура дозволяє Flutter працювати на всьому, у чого є GPU і екран. Зараз підтримується iOS і Android. Web і desktop — в активній розробці.

One team. Одна команда і одна кодова база дозволить істотно заощадити на розробці.

Незважаючи на молодість фреймворку, він одержав широке поширення ще до релізу першої версії. Найбільш скачиваемыми додатками, що використовують Flutter, є:

До релізу першої версії Flutter відбувся Flutter Live Event, на якому фреймворк представили широкій публіці. Разом з ним представили інструмент Flare для створення анімацій і CI/CD-систем від Codemagic спеціально для Flutter. Анонсований широкий набір інструментів для розробника і підтримка основних IDE:

На додаток до цього, є сайт , на якому перераховано величезна кількість додатків, написаних на Flutter. Є окрема книга , яка розповсюджується безкоштовно і описує досвід та історії успіху розробки 17-ти додатків з допомогою Flutter.

Як вже згадувалося вище, Flutter сконцентровано на вирішенні проблем бізнесу (вартість розробки) та розробника (зручність і швидкість). Для цього Google вклав величезні зусилля в тулинг для розробки.

Widget inspector. Навігація по дереву віджетів. Клацання по віджету відправить вас до того місця, де він викликається в коді.


Debug. Підтримка дебага з вікна IDE. Досить поставити точку зупинки і запустити додаток в debug режимі.


Debug paint. Побудова відступів і маркерів позиціонування для швидкого розуміння того, що впливає на положення елемента.


Repaint rainbow. Постійно змінюється веселка навколо елементів, які перерисовываются. Це дозволяє відстежити небажану активність.


Performance window. Дозволяє стежити за швидкістю відтворення і кількістю перерисовок окремих компонентів. Якщо якийсь віджет буде занадто активним, спиннер зліва від колонки забарвиться в жовтий або червоний колір.


Profiling. Використовується для глибокої налагодження роботи програми.


Порівняння з React Native

Порівняння з React Native я б почав з github-репозиторіїв. Це перше, що бачить розробник на підході до вибору технології.

Статистика GitHub за червень 2019 року

React Native Flutter
Stars ~78k ~67k
Github issues 513 5k+
Proposed PR 29 54
Об'єднані PR 0 394
Closed issues 173 619
New issues 124 822

Зі статистики видно, що Flutter молодий і динамічно розвивається фреймворк. По зоряному рейтингу він впритул наблизився до React Native, в той час як за кількістю відкритих issues, має десятикратне перевагу. 5К issues, а також той факт, що кількість нових issues перевищує кількість закриваються, говорить про стрімкий розвиток як ком'юніті, так і платформи. Її активно тестують і репортят баги. Сюди ж варто віднести і велику кількість закриваються ПР, що також говорить про активне спілкування і підтримки.

Переваги, які обіцяє нам кожен з пари, я розділив на такі основні категорії:

Write once. Суть кросплатформених фреймворків в обіцянці «написав раз — запустив скрізь». В обох випадках на 100% цього не досягти. Але за рахунок того, що Flutter самостійно контролює малювання, жести і анімації, проблем з подпиранием нюансів тієї або іншої платформи буде завжди менше. React Native, покладаючись на ОЕМ-віджети, не завжди може забезпечити гладкий і безпроблемний зовнішній вид на обох платформах.

Learn once. React Native, маючи у своїй основі ReactJS, виграє за рахунок великої популярності як самої мови JavaScript, так і React-фреймворка. Навіть якщо своє знайомство з React ви почнете з React Native, для вас не складе великої праці перейти на web-розробку. І навпаки: маючи в штаті React-розробників, можна досить швидко почати працювати з React Native. У випадку з Flutter, є великі перспективи з запуском на будь-яких платформах», але на даний момент він не може змагатися нарівні.

Bundled components. В комплекті як з React Native, так і c Flutter, йде готовий набір компонентів (UI, анімація, верстка), але перевага все ж за Flutter, так як кожен з існуючих компонентів буде отрисован на обох платформах. Можливо, деякі будуть виглядати чужорідно на сторонньої платформі, але питання пошуку та підбору компонентів на заміну iOS-версіями віджетів Android вирішується. Хорошим прикладом буде PickerIOS, аналогів якому за зовнішнім виглядом немає в Android. Доводиться вдаватися до допомоги сторонніх компонентів, наприклад, 'recat-native-wheel-picker-android'.

Performance. Підсумкове додаток на Flutter буде представляти собою нативний код, який при інших рівних умовах буде завжди швидше JavaScript.

Third party libs. React Native тут поза конкуренцією. NPM надає нам безліч бібліотек на будь-який смак. У той же час DartPub, зважаючи на молодість платформи, не володіє таким багатством вибору. Безліч бібліотек, якщо і є, все ще молоді.

World wide usage. Незважаючи на те, що Flutter набирає популярність і має активно розвивається ком'юніті у світовому масштабі, він все ще не може обійти React Native за популярністю (відповідно Google Trends , виняток складає США).

Developer experience. Порівнюючи відчуття при розробці, Flutter нокаутує React Native за якістю і кількістю всіляких інструментів для розробника.

Debug and Profiling. Flutter має окремий режим складання додатка, який допомагає в профілюванні та налагодження складних кейсів. У той же час для React Native це більш трудомісткий і складний процес.

Code push. На даний момент аналогів у Flutter не існує. Розробники стверджують, що ця задача вирішується. Якщо для когось ця функція важлива, є issue на github , за яким можна стежити.

React Native Flutter
Write once +/- +
Learn once + +/-
Included components PR - +
Third party libs + -
Performance - +
World wide usage + -
Developer experience - +
Debug and Profiling - +
Code push + -

В результаті, обидва фреймворку за абсолютною сумою балів йдуть практично нарівні: 4,5 (React Native) проти 5,5 (Flutter). Але кожен з вас може зробити свій висновок. Кому-то може бути життєво необхідний code-push, і заради цього він готовий битися із засобами розробника в React Native. Для кого-то хайповость, інструментарій і потенціал можуть стати вирішальним фактором у виборі на користь Flutter. Третім — Dart стане непереборною перешкодою. А четвертим, навпаки, на душі Dart, який вони в таємниці від всіх вивчають вже рік поспіль. На практиці, на підсумкове рішення впливають не стільки зірочки в репозиторії і фішки фреймворку, скільки безліч факторів навколишнього середовища конкретного проекту і бізнесу.

Порівняння архітектур


З архітектурної точки зору, у цих фреймворків мало спільного. Спільним є платформа, на якій запускається додаток, і, в деякому розумінні, спосіб взаємодії з сервісами, що надаються платформою. В іншому вони принципово різні.

Flutter працює безпосередньо з канвасом і подіями, сам малює віджети, має власну модель лейаута і рендера. React Native повністю спирається на OEM-віджети, які надає платформа і має прошарок у вигляді движка Yoga, який реалізує флексбокс лейаут на стороні платформи, а рендеринг вже повністю залежить від платформи.

Flutter компілюється в нативний код, а React Native виконується всередині JavaScriptCore, що не найкращим чином впливає на швидкість запуску і роботи програми. У React Native всі взаємодія з платформою відбувається через бридж, який додає накладні витрати на серіалізацію/десеріалізацію даних між середовищем виконання JS і нативним кодом.

У Flutter є Platform Channels, які працюють подібним з бриджем чином, для реалізації взаємодії з сервісами платформи (сенсори, камера тощо), але за рахунок нативного коду працюють істотно швидше. Варто також згадати, що дні бриджу полічені, так як React Native переходить на архітектуру з JavaScriptInterface, щоб позбутися від оверхеда на бриджі.

Останнім відмінністю є мова, яка використовується для написання коду. У React Native — це JavaScript зі всіма його плюсами і мінусами, під Flutter — відносно молодий мова Dart, який свого часу був розроблений з метою замінити JS.

«За» і «Проти» використання Flutter

«За»:

Хайп. Технологія явно спіймала хвилю успіху, має активно розвивається ком'юніті і цікаві архітектурні підходи у своїй основі. Це, на мій погляд, запорука тривалого і успішного існування фреймворка.

Швидке написання коду. Власний рендеринг, незалежність від OEM-віджетів і багатий інструментарій розробника істотно прискорює написання коду і підтримку двох платформ одночасно.

Один і той же код запускається на двох і більше платформах. На даний момент повноцінно підтримуються тільки iOS і Android. Web і desktop — в активній розробці. Але їх вихід у продакшн — питання найближчого майбутнього.

Менше тестування. За рахунок pixel perfect rendering, тестування та усунення платформо-залежних багів і нюансів верстки буде проходити значно швидше.

Швидкодія. Компіляція в нативний код не залишає сумнівів в цьому твердженні.

Однаковий UI на всіх пристроях. При необхідності написати додаток з унікальним дизайном, який повинен бути однаковим на двох мобільних платформах, Flutter стає незамінним інструментом для кроссплатформної розробки.

«Проти»:

Зрілість. Молодість платформи — неминучий супутник Flutter. У цьому випадку, React Native — більш стале рішення, під яке буде легше знайти розробників.

Крута крива навчання. Dart додає накладні витрати на впровадження Flutter за рахунок необхідності вивчати і вникати в новий мову.

Нові нативні UI компоненти. У випадку з React Native, вони можуть бути підключені в проект досить швидко. У Flutter все нові з'являються на стороні платформи елементи UI повинні бути заново отрисованы.

Необхідність продати технологію менеджеру на поточному етапі її розвитку. З кожним днем зробити це буде все легше і легше. Але на даний момент це досить сильний бар'єр. Потенціал відправити в Google graveyard. Судячи по вкладених ресурсів та PR-активності, це результат малоймовірний, але шанс є завжди.

Відсутність вакансій на ринку. На даний момент їх дуже мало. Це повинно змінитися в майбутньому. Але зараз це може стати перешкодою для розробника, який не хоче вкладати свої сили в вивчення нової технології.

Побоювання, що Flutter не здатний закрити потреби бізнесу. Обіцяючи успішну роботу на всьому, у чого є GPU і екран, може виявитися запускаються скрізь, але не бути затребуваним у бізнесі.

Підсумки

Підводячи підсумки, хочу провести паралель між Flutter і браузером. Можливо, комусь це здасться несподіваним, але, на мій погляд, така паралель має місце бути. Так само, як браузер рендерить вміст веб-сторінки практично на будь-якому пристрої і під будь-якою операційною системою, Flutter рендерить віджети. Замість HTML+JS зв'язки, у Flutter виступає скомпільований Dart-код. Замість протоколу HTTP, дистрибуція коду здійснюється за допомогою вендор-магазинів.

На сьогодні браузери міцно влаштувалися на всіх платформах і досить прийнятно відображають сторінки будь-якої складності. Навіть ті, які не були спеціально оптимізовані для них. Тобто це не є чимось недосяжним.

Я вважаю, що успіх Flutter залишається питанням часу, помноженому на зусилля ком'юніті і підтримки Google з написання production-ready ембедеров для всіх найбільш популярних платформ.


Flutter завойовує світовий ринок. В підтвердження цьому — карта зі списком подій, присвячених Flutter по всьому світу: від Нью-Йорка (США) до Уйо (Нігерія), від Токіо і Осаки (Японія) до Нюрнберга (Німеччина). Пропоную всім, хто цікавиться і працює з Flutter, об'єднуватися і створювати локальне ком'юніті в Україні. Приєднуйтесь до нашої групи «Art Flutter» в телеграме.


Читайте також: «Створення додатку на Flutter: перші кроки»

Опубліковано: 03/07/19 @ 07:00
Розділ Різне

Рекомендуємо:

Як я працюю: Ліна Кононенко, UX Lead в Wix/DeviantArt
Як добитися взаєморозуміння з клієнтом: 5 простих правил
AI & ML дайджест #13: додатки GANs, тренди в NLP, колекція шпаргалок
ANTLR: неформальне введення
AR для військових: як «бачіті крізь броню» та вражати ворожу техніку за допомогою системи від LimpidArmor