Привет, всем привет, меня зовут Го Шуйю, автор книги "Практическое руководство по разработке приложений с использованием Flutter" и ответственный за открытое программное обеспечение проекта GSY, таких как gsy_github_app_flutter и GSYVideoPlayer.
Как вы можете догадаться, тема сегодняшнего обсуждения не является чисто технической презентацией; можно сказать, что это попытка объяснить сложную ситуацию. Хотя я редко занимаюсь такими темами, мне кажется, что сейчас есть необходимость создать такой справочный материал.
Я начал работать с Flutter примерно в 2017 году. Это было забавно — тогда мне требовалось провести внутреннюю презентацию по технологиям кросс-платформенного программирования, главной целью которой было продвижение фреймворка React Native среди других отделов компании. К моему удивлению, именно тогда я наткнулся на Flutter и решил добавить его в качестве дополнительного элемента в свою презентацию. Так началась моя история с Flutter.
С момента выпуска Flutter прошло уже почти семь лет. В 2022 году можно смело сказать, что Flutter больше не является малочисленным кросс-платформенным фреймворком.
Как показывает эта диаграмма, на момент моего скриншота в феврале, Flutter имеет более чем 137 000 звёзд на GitHub, а также более 10 000 открытых и более 50 000 закрытых запросов на исправление ошибок, что свидетельствует о высокой активности сообщества и пользователей.
По официальным данным, Flutter уже значительно опередил другие кросс-платформенные фреймворки и стал самым популярным средством кросс-платформенной разработки мобильных приложений. По состоянию на февраль 2022 года, около 500 000 приложений используют Flutter.
Как видно из этой диаграммы, согласно исследованию данных во второй половине прошлого года, Flutter занял первое место среди самых используемых и любимых кросс-платформенных фреймворков. Можно заметить значительный рост использования Flutter с 2019 по 2022 годы, где около 42% кросс-платформенных разработчиков используют этот фреймворк.
На самом деле, в последние два года я делал некоторые простые статистические исследования:
libflutter.so
, libreactnativejni.so
и libweexcore.so
. В случае использования плагинов для распространения, некоторые приложения могут быть пропущены.Как видно, использование Flutter и React Native составляет около 50%, тогда как доля Weex значительно ниже. Кроме того, на основе этой небольшой выборки можно заметить, что большинство современных приложений используют различные кросс-платформенные фреймворки.
При этом, выделенные жирным шрифтом приложения используют более одного кросс-платформенного фреймворка по причине бизнес-потребностей, такие как UC Browser, Xianyu и другие. Анализируя официальные данные за четвертый квартал прошлого года, можно отметить, что за последние шесть месяцев 72% и 91% разработчиков использовали Flutter для создания приложений для iOS и Android соответственно.
Рассмотрим ещё одну статистику, полученную с платформы pub.dev, которая является хостингом для сторонних пакетов Dart. Данные основаны на информации от 22 февраля 2022 года:
Все | 23495 пакетов |
---|---|
Flutter | 21714 пакетов |
Android/iOS | 20352 пакетов |
Веб | 12584 пакетов |
ПК | 14314 пакетов |
Null Safety | 12615 пакетов |
По данным официального исследования за четвертый квартал, можно заметить, что процент использования Flutter в качестве основной технологии для разработки постепенно увеличивается.
И последнее, стоит упомянуть идею, которую всегда пропагандирует официальная команда Flutter:
Независимо от того, насколько хорош SDK, если он используется лишь небольшим количеством людей, его ценность будет невелика; даже если SDK сам по себе не очень хороший, но если им пользуется большое количество разработчиков, это создаст здоровую и процветающую экосистему, благодаря которой те, кто использует этот фреймворк, смогут получать выгоду.> К слову, знаете ли вы, какой аспект Flutter вызывал больше всего недовольства по результатам опроса?
Это текстовый редактор! По данным за четвертый квартал, удовлетворенность функциями редактирования текста упала с 82,3% (однострочный режим) и 82,2% (фильтрация и форматирование) до 69,6% (мультистрочный режим) и 66,6% (редактор с богатым форматированием). На текущий момент опыт работы с мультистрочным редактированием и поддержка ввода текста с богатым форматированием действительно не слишком удобны.## Flutter против других
Поговорив о текущем положении дел с Flutter, давайте обсудим некоторые очевидные сравнения между Flutter и другими фреймворками.
Эта тема уже была затронута множество раз, поэтому мы кратко рассмотрим её. Во-первых, сравним принципы реализации каждого из этих фреймворков, как показано на следующих диаграммах:
Для React Native/Weex и подобных проектов контролы выполняются внутри своих движков JavaScript, а затем отображаются как native контролы с использованием native возможностей отрисовки.
Для uni-app и подобных гибридных кросс-платформенных фреймворков используются возможности отрисовки WebView; (не рассматривается случай использования Weex).
Сначала заметим, что теоретически Flutter наиболее близок к native реализации, так как путь его выполнения аналогичен native, в то время как RN/Weex несколько уступают, а uni-app использует отрисовку WebView и находится на последнем месте.Однако, когда дело доходит до производительности, на самом деле часто ограничивающим фактором является не сам фреймворк, а разработчик, который использует его. Я видел приложения, созданные с помощью Cordova, которые были очень хорошо оптимизированы по производительности и удобству использования. В одном из моих выступлений на конференции я говорил с представителем Alipay, который отметил, что компания также использует много технологий hybrid на основе H5, и благодаря собственному ядру UC они обеспечивают отличную производительность и опыт пользователя.
Затем мы сравним размер сборки приложений, главным образом для Android, поскольку размер приложений для iOS всё реже становится предметом внимания, как это было с QQ:
Возвращаясь к вопросу о размере приложений, ранее мне попались мнения многих людей:
"Compose использует Kotlin/JVM для создания JAR/AAR файлов для JVM и Android платформ, Kotlin/Native для создания Framework файлов для iOS платформы и Kotlin/JS для создания JavaScript файлов для Web платформы. В конечном итоге вызывается native API, что позволяет использовать Compose Multiplatform без потери производительности и без увеличения объёма приложения, как это происходит с Flutter."
Да, если судить по реализации, Flutter действительно должен занимать больше места по сравнению с Compose. Но какова реальная ситуация?Сначала создаем несколько пустых проектов, а затем при сборке оставляем только связанные с arm64-v8a динамическими библиотеками, так как обычно на устройстве остается одна такая библиотека .so.
Не добавляя ни одной строки кода, собираем release версию для Android и получаем следующие результаты:
Из полученного результата видно, что пустой проект Flutter действительно больше по объему, чем проект Compose. Однако стоит обратить внимание на следующие моменты:
Вкратце, контроллеры Compose и нативные контроллеры представляют собой различные системы. Если вы посмотрите на скомпилированный код, то заметите, что контроллеры типа BOX в конечном итоге реализуются через фреймворк ComposerKt и BoxKt для выполнения отрисовки и рисования.
Поэтому после компиляции Compose не преобразуется в нативные Android View для отображения, а использует платформенный Canvas, что делает его похожим на Flutter. Можно сказать, что Compose представляет собой новую систему View.
Кроме того, стоит отметить, что хотя это и новая система View, компоненты Compose могут отображать границы интерфейса на устройствах Android.
Что касается объема, поскольку у меня есть ряд открытых проектов GSY, которые имеют схожую бизнес-логику, мы можем сравнить их размеры после сборки в режиме release.
Поскольку у меня пока нет проекта с использованием Compose, здесь представлен сравнительный анализ нативной реализации.- Проект Flutter увеличился с пустого размера в 5,7 МБ до 9,8 МБ, что составляет прирост в 4,1 МБ;
Хотя это не совсем точные данные, можно заметить, что при примерно одинаковых бизнес-ценностях общая величина проектов Flutter и нативного приложения отличается не сильно, а прирост размера нативного проекта даже больше, чем у Flutter.
Однако данное утверждение справедливо при условии, что нативный проект не использует компрессию и минификацию. При активации этих процессов, как показывают следующие графики, объем приложения значительно уменьшается — от 9,3 МБ до 6,4 МБ. Таким образом, можно сделать вывод, что после применения минификации и компрессии, прирост размера нативного приложения будет сравнимым с приростом размера Flutter.
Кроме того, я нашел проект на чистом Compose и провёл тестирование после применения минификации и компрессии. В результате объём Compose значительно уменьшился: с 9,6 МБ до 2,4 МБ, благодаря тому, что большинство классов в Compose могут быть успешно минифицированы.
Итоги:
Конечно, это не абсолютное правило, поскольку размер приложения может зависеть от привычек разработчиков. Например, однажды мне попался случай, когда библиотека бизнес-логики Flutter одного приложения достигала 77,4 МБ.
Это какое понятие? Обычно, размер Flutter динамической библиотеки для обычной средней или маленькой приложения составляет около 10 МБ - 15 МБ, а для крупных приложений обычно контролируется в диапазоне от 20 МБ до 35 МБ. Даже если это очень большой объём, например, UC составляет 35 МБ, а корпоративный WeChat — 28,9 МБ.
Поэтому размер больше зависит от субъективного контроля разработчиками, также он связан с тем, включили ли вы оптимизацию путём запутывания и сжатия. Основная цель этого раздела — помочь вам получить более конкретное представление о различных проектах и их сборочных продуктах, чтобы предоставить основание для выбора подходящей платформы разработки.### Процесс сборки
Давайте поговорим о процессе сборки. Почему мы говорим об этом? Потому что для новичков проблемы во время сборки могут стать причиной отказа от дальнейшей работы.
На следующем рисунке показана типичная проблема, которую часто встречают при использовании Flutter вместо нативного программирования:
Если после запуска вы видите, что процесс застрял на этапе assembleDebug
, то это значит, что Android скачивает необходимые зависимости через интернет, такие как Gradle SDK и AAR библиотеки. Этот процесс не отображается при выполнении команд flutter run
или запуске через IDE. Чтобы увидеть прогресс, вам нужно будет перейти в директорию android/
и выполнить команду ./gradlew assembleDebug
.
Например, в официальном опросе Flutter Q4 было установлено, что самыми распространенными проблемами при выпуске приложений являются работа с Xcode (для iOS) и Gradle (для Android). Почему это важно? Во-первых, это указывает на то, что недостаток знаний о нативных платформах может стать болезненной точкой использования кросс-платформенного программирования.
Конечно, среди всех кросс-платформенных решений Flutter хотя бы не является худшим, но React Native точно можно назвать самым слабым звеном. Независимо от того, используете ли вы Weex или React Native, проблема с node_modules всегда была головной болью.
Пример: черная дыра
node_modules
в проектах React Native часто приводит к непредвиденным проблемам при установке и запуске в различных окружениях. Различные плагины и инструменты становятся источниками проблем, особенно когда они делают проект более громоздким. Вот пример проблемы, с которой я столкнулся недавно:
Зависимости внутри зависимостей требуют разных версий среды Node.js, что заставляет меня находить подходящую версию среди всех этих вариантов. Конечно, это ещё не самое сложное. Самое сложное — это когда проект успешно запускается на компьютере А, а затем на компьютере Б после выполнения команды npm install
, он отказывается работать. Это обязательный урок для каждого разработчика React Native.
Из точки зрения фронтенд-разработки, использование плоских зависимостей может сделать структуру зависимостей менее очевидной, так как количество файлов и директорий становится значительным. Однако современные инструменты управления зависимостями, такие как npm и pnpm, уже внедрили оптимизации для решения этой проблемы,в то время как Flutter гораздо легче в этом отношении. В настоящее время уровень вложенности пакетов Dart очень мал, и пути к этим пакетам достаточно понятны. Именно поэтому мне кажется, что Flutter намного удобнее React Native в этом плане, поэтому при одинаковой сложности зависимости от платформы, Flutter действительно проще начинать работу с "Hello World", чем React Native.### Flutter & Compose
И последний момент: сравнение между Flutter и Compose.
Многие уже видели сравнение между Flutter и React Native, поскольку React Native существует уже давно, и эти технологии поддерживаются различными компаниями. Но что касается Flutter и Compose, они являются открытыми проектами Google и поддерживают многоплатформенный подход. Какие же различия между ними? Какой выбор стоит сделать?
Сначала немного отступлю от темы: фронтенд использует npm, Flutter использует pub, iOS использует CocoaPods, вы можете найти нужные библиотеки через официальные сайты этих систем, просмотреть информацию о популярности, версиях, совместимости и количестве использования. Но что насчет Android?
Неужели система сборки Android Gradle не имеет такого удобства, чтобы мы могли просто искать нужные библиотеки через ключевые слова на GitHub? Этот пробел влияет на развитие Compose в контексте многоплатформенного программирования. Сначала официальное определение от Google, Compose — это современный нативный пакет инструментов пользовательского интерфейса для Android, и как мы уже говорили ранее, это новая система UI, поэтому Compose имеет свою платформу, а именно Android, где он работает в своей среде.
Из доступной дорожной карты видно, что Google сосредоточил свои усилия на нативной платформе Android, а реализация Compose Multiplatform осуществляется командой JetBrains через compose-jb.Flutter не имеет своей собственной платформы, он представляет собой кросс-платформенную систему пользовательских интерфейсов, созданную специально для работы на нескольких платформах. На данный момент Flutter поддерживает официально Android, iOS, Web и Windows, а поддержка Linux и macOS находится в процессе разработки.
Поэтому одной из главных отличий между ними является то, что Compose был спроектирован Google для создания нового UI для Android, а JetBrains расширили его возможности до кросс-платформенного использования, тогда как Flutter был создан с целью работы на множестве платформ.
Хотя оба они поддерживают кросс-платформенные решения, между ними есть значительные различия, как показано на следующем рисунке:
Основное различие заключается в том, что Flutter использует единую официальную библиотеку для поддержки различных платформ, в то время как Compose пока использует различные модули для поддержки разных платформ.
Flutter, конечно же, компилируется с использованием различных команд для каждой платформы, при этом используется общая библиотека Flutter для выполнения задач. В настоящее время логика реализации Compose для Web, Desktop и Mobile может не совпадать, особенно для Web.> В настоящее время официальная поддержка Compose для iOS ещё недоступна, хотя существуют способы её использования, но они пока не очень удобны. Для Web Compose требуются специальные пакеты, которые отличаются от тех, что используются для Mobile и Desktop, где можно использовать общий набор compose-ui
.Например, в compose-jb поддержка Web реализуется следующим образом, как видно из импортируемых и используемых компонентов:
import org.jetbrains.compose.web.dom.*
import org.jetbrains.compose.web.css.*
fun main() {
var count: Int by mutableStateOf(0)
renderComposable(rootElementId = "root") {
Div({ style { padding(25.px) } }) {
Button(attrs = {
onClick { count -= 1 }
}) {
Text("-")
}
Поэтому с точки зрения Compose:
С практической точки зрения, независимо от того, начали вы изучение с Compose или Flutter, это поможет вам освоить другую технологию. Учеба одной технологии даёт около 70% понимания другой:
Конечно, многофункциональность возможна благодаря существованию соответствующих платформенных версий. Многие проблемы, связанные с платформами, требуют решения именно на этих платформах. Те, кто говорит о том, что "ваш страх станет их прибылью", забывают, что без платформенного уровня нет смысла говорить о многофункциональности.
Наконец, давайте обсудим некоторые мои мысли.
До появления Flutter, основные принципы мобильной многофункциональности сводились к двум вариантам:
Однако это не значит, что Flutter всегда является оптимальным решением для реальных сценариев использования. Вместо этого вам следует оценивать свой бизнес-сценарий, чтобы выбрать наиболее подходящий фреймворк, например:
Раз уж мы говорим о горячем обновлении, давайте кратко рассмотрим проблему горячего обновления. Во-первых, официальная поддержка горячих обновлений от Flutter отсутствует, в отличие от React Native, который предлагает очень зрелый и универсальный фреймворк code-push
.> Почему? Во-первых, код JavaScript в React Native представляет собой чистый текстовый скрипт; даже если он собран в бандл, он остаётся в виде чистого текста. Поэтому отправка текстового бандла через code-push
не противоречит правилам, а code-push
не может отправлять собранный нативный код, поскольку это было бы некорректным.
Когда Flutter собирается с помощью AOT, получается исполняемый двоичный файл. Отправка такого файла через механизм горячего обновления будет нарушать правила Apple App Store и Google Play.
Можно ли делать горячие обновления в Flutter?
Ответ — да, можно. Учитывая необходимость горячих обновлений в Китае, появились различные сторонние решения, такие как:
MxFlutter (Tencent), Fair (58.com), liteApp (WeChat Work), Flap (Meituan MTFlutter) и flutter_code_push (Chimera).
Эти решения не отправляют собранный двоичный код напрямую; например:
Эти подходы требуют некоторых жертв ради горячего обновления, поэтому с точки зрения Flutter всегда был "недружелюбен" к этому вопросу.
Конечно, если вы не публикуете приложение на Google Play, то горячее обновление SO динамической библиотеки на Android не является значительной преградой, так что вы можете использовать уже существующие плагины для решения этой задачи.### Кросс-платформенные возможности
Наконец, хочу сказать несколько слов о многоплатформенной поддержке Flutter. Вспомните ли вы ранее упомянутую фразу "Создайте приложения для любого экрана"? А Flutter — это же Write Once, Run Everywhere, верно? Официально поддерживаются сборки для Android, iOS, Web, Windows, MacOS и Linux всего за один набор кода?
Из моего опыта могу сказать, что идея "Write Once, Run Everywhere" звучит замечательно, но на практике она далека от реальности. Да, Flutter действительно позволяет запустить один и тот же код на всех платформах, однако текущий опыт показывает, что затраты времени и усилий на адаптацию одного кода ко всем платформам значительно выше того удобства, которое они предоставляют.
Давайте начнём с Web. Web-платформа среди всех остальных наиболее специфична, поскольку ей требуется поддерживать логику работы как на мобильных устройствах, так и на ПК. На данный момент Flutter Web:
HtmlCanvas
для отображения на мобильных устройствах, что приводит к проблемам с интеграцией и адаптацией API;CanvasKit
для отрисовки на ПК, но технология wasm
пока слишком "революционна", что вызывает проблемы с размерами, SEO и совместимостью;**Поэтому использование Flutter Web на данный момент ещё не совсем удобно, хотя его стабильные версии имеют значение именно потому, что ваш код может быть собран в виде web-приложения!**После создания приложений для Android и iOS вы сможете быстро создать веб-страницы для части вашего пользовательского интерфейса (UI) и бизнес-логики, что делает этот подход ценным. Таким образом, вам совершенно не обязательно реализовывать эти части заново.
Например, проекты Ali Seller, Meituan Waimai Classroom и другие используют Flutter Web.
Перейдём теперь к ПК. Логика работы приложений на ПК отличается от мобильных устройств: мышь, клавиатура, возможность изменения размера окна, поворот экрана, прокрутка и прочее. Эти аспекты сложно объединить одним кодом. По моему мнению, лучше всего использовать те же компоненты, анимации, UI, списки и бизнес-логику, которые работают на Android и iOS, и применять их там, где это возможно. Если вам нужна хорошая производительность, я бы рекомендовал разделить проекты для ПК и мобильных устройств. Если действительно требуется одна общая система, есть некоторые хорошие поддержки, такие как: responsive_framework
.
Вы можете оставить комментарий после Вход в систему
Неприемлемый контент может быть отображен здесь и не будет показан на странице. Вы можете проверить и изменить его с помощью соответствующей функции редактирования.
Если вы подтверждаете, что содержание не содержит непристойной лексики/перенаправления на рекламу/насилия/вульгарной порнографии/нарушений/пиратства/ложного/незначительного или незаконного контента, связанного с национальными законами и предписаниями, вы можете нажать «Отправить» для подачи апелляции, и мы обработаем ее как можно скорее.
Опубликовать ( 0 )