14 мая Flutter зарелизили новую версию 3.22. Подробнее об этом тут (мы всё заботливо перевели и художественно отредактировали), оригинал здесь.
Наша Flutter-команда не могла остаться в стороне и уже опробовала новинку. Делимся мнением.
Марк Абраменко, Engineering Manager во Flutter-отделе Surf
Макросы в Dart
Забавно, но на секции QnA на московском митапе Flutter от нашей команды, когда отвечал на вопрос про статическое метапрограммирование, я сказал, что вряд ли нам стоит ждать этого в ближайшие годы.
И всего через 3 недели команда Dart анонсирует использование макросов в языке.
Именно анонсирует, потому что на самом деле макросов в Dart 3.4 нет. Чтобы их попробовать, нужно переключиться минимум на 3.5.0-152 dev-канала, либо на master-ветку (!) Flutter.
В статье, кстати, фичу пообещали выкатить только к началу 2025 года.
Команда Dart в анонсе пообещала выкатить отдельный язык (набор ключевых слов), который будет использоваться для написания макросов. Сейчас же они выпустили первый пакет, который использует макросы — json. В пакете уже можно найти новые ключевые слова:
macro — для объявления аннотации;
augmented — для просмотра результата генерации.
Интересно, что название пакета “json” держали целых 10 лет для этого апдейта:
![](https://habrastorage.org/getpro/habr/upload_files/81a/76d/eda/81a76deda3a38e8b7cba6b12b4ecd1ee.jpeg)
Несмотря на то, что эта фича находится в зачаточном состоянии, работает всё достаточно неплохо.
Чтобы попробовать JsonCodable, нужно пройтись по официальной инструкции: поставить определённую версию Dart и Flutter, выставить флаги experimental, добавить пакет json.
В VSCode с предрелизными версиями плагинов уже всё работает достаточно неплохо: плагин понимает новые ключевые слова, работает предпросмотр генерации кода, анализатор не ругается на “неявные” методы (toJson, fromJson).
![](https://habrastorage.org/getpro/habr/upload_files/b1d/4ac/b92/b1d4acb92b7f261855441198fb90f5d4.gif)
Некоторые справедливо критикуют аналоги статического метапрограммирования (рефлексию, мирроринг) за то, что она лишает нас безопасности на уровне компиляции — что-то точно может «выстрелить» в рантайме. Фича с «предпросмотром» сгенерированного кода привносит больше прозрачности в этот процесс. Если анализатор Dart будет работать с «предпросмотром», это значительно повысит привлекательность рефлексии по сравнению с другими языками.
Могу с уверенностью сказать, что рано или поздно такие пакеты как freezed, injectable и auto_route перейдут на кодогенерацию в рантайме. А в ближайший год мы с вами точно будем использовать build_runner.
Блюр переписали с нуля?
Об исправлении блюра при работе с PlatformView нам поведали ещё в версии 3.7. И, на мой взгляд, тогда работать он стал хуже. Версия 3.22 исправила многие проблемы, но не все.
Здесь небольшой проект с демонстрацией проблем на iOS при работе с PlatformView на примере работы с вьюшкой карт. Это экран со Scaffold, в body которого находится PlatformView с iOS. Сам Scaffold находится в Stack и его целиком перекрывает блюр.
Первый пример накладывает блюр на экран целиком. Это демонстрация того, как блюр во Flutter работает в нормальных условиях без PlatformView.
![](https://habrastorage.org/getpro/habr/upload_files/648/4fc/f56/6484fcf566a76edc047879a11e41b7af.png)
Второй пример демонстрирует типичное использование блюра — алерт на iOS. Раньше блюр просто не появлялся, если в зоне видимости есть PlatformView.
![](https://habrastorage.org/getpro/habr/upload_files/e2f/63a/616/e2f63a616425c6144b617e18e790e834.gif)
В версии 3.7 блюр появился, но у него не было анимации. И это выглядело даже хуже, чем было раньше. В версии 3.22 проблему, наконец, исправили.
Третий пример — Flutter-виджет находится поверх PlatformView. В «исправлении» 3.7 мы видим странное поведение — виджеты блюрятся выборочно.
Версия 3.22 частично исправляет это поведение. Выглядит всё ещё плохо.
![](https://habrastorage.org/getpro/habr/upload_files/610/157/7e5/6101577e5d4cc3998aab7ada877b5510.png)
Четвёртый пример — блюр с анимацией. Все 3 версии пока не отображают адекватное поведение.
![](https://habrastorage.org/getpro/habr/upload_files/6c8/9d4/8f6/6c89d48f6f5015d444cab92b604d9e67.gif)
Максим Яковлев, Flutter-разработчик, Surf
Релиз WASM
Пожалуй, самое заметное изменение в релизе Flutter 3.22 и Dart 3.4 — это поддержка компиляции наших приложений в WebAssembly для исполнения их в браузере.
wasm — это не очередной убийца js и не будущая замена html/css/js.
WebAssembly — это технология, которая позволяет низкоуровневым языкам программирования, таким как С++, Rust, Go исполняться в безопасном контейнере, внутри браузера прямо на движке V8, так же, как это делает javascript.
Для простоты можно воспринимать его как FFI, но для веб‑приложений. И сфера применения довольно схожа.
Наверное, не лучшей идеей будет перенос в wasm модули простой бизнес‑логики: изменение цвета кнопки в UI, навигация, авторизация или http‑запросы. Это не даст ощутимых изменений производительности.
Но все, что связано с вычислениями, будь то расчет анимаций, расчет положения кривых на конвасе, любые криптографические операции — тут wasm показывает преимущество в скорости исполнения перед js. И скорость эта сопоставима со скоростью исполнения тех же операций в нативных приложениях.
Получается, компиляция в Flutter приложений в wasm — отличная идея. Ведь все, что видит пользователь, отрисовывается силами SKIA и Flutter framework. А прирост скорости вычислений положительно сказывается на пользовательском опыте.
![](https://habrastorage.org/getpro/habr/upload_files/b2d/a8a/03c/b2da8a03c32693ccc23e55ea1e12bd76.png)
Flutter engine, реализованный на С++, давно был скомпилирован в wasm и активно используется текущими приложениями. Это увеличило производительность и сократило время отрисовки кадра. Но анимации и скролл рассчитываются в Flutter framework слое, реализованном на dart.
До недавнего времени компиляция языков со сборщиком мусора в WebAssembly была недоступна и эта часть движка компилировалась в js, что вызывало явный недостаток производительности.
Но теперь, благодаря совместным усилиям команды Dart, Chrome и других участников сообщества реализован стандарт WasmGC, который позволяет компилировать высокоуровневые языки программирования со сборщиком мусора в wasm.
Благодаря чему, теперь все приложение, включая зависимости, компилируется в WebAssembly.
![](https://habrastorage.org/getpro/habr/upload_files/96f/a18/6e0/96fa186e032d980be3f40bbb846bfc99.png)
Мы были бы не мы, если бы не попробовали собрать одно из наших веб-приложений в wasm.
Инфраструктура для этого почти готова, большая часть популярных библиотек адаптирована. Сложности возникли только с транзитивными зависимостями, но исправление проблем заняло у нас 20 минут.
Результат впечатляет:
![](https://habrastorage.org/getpro/habr/upload_files/d0e/2d5/d41/d0e2d5d41f082a79db215a04ac6ccfcf.gif)
Здесь видно, что отрисовка анимаций заметно улучшилась. В первом случае кадр рендерится только силами js. На выходе мы видим 2 кадра при открытии drawer menu.
Во втором случае используется skia, скомпилированный в wasm. Дела тут чуть лучше, но отсутствие плавности и микрофризы интерфейса заметно.
Последний пример — это версия приложения, скомпилированная полностью в WASM. Число кадров увеличилось чуть меньше, чем в 2 раза, в сравнении с skia wasm.
Интерфейс веб-приложений стал намного плавнее и приятнее. Некоторые отметили, что шрифты и векторные изображения стали более сглаженные. В целом, внешний вид и опыт взаимодействия заметно приблизился к нативным приложениям. А это уже открывает дорогу по-настоящему классным PWA приложениям уже сейчас.
Но не все так расчудесно:
Полная поддержка WasmGC сейчас есть только в Google Chrome в версии 119 и выше;
![](https://habrastorage.org/getpro/habr/upload_files/b21/76a/5ab/b2176a5ab00c18c08909a5c5c0f7cdd2.png)
Спецификация поддерживается в Firefox 120, но есть ряд проблем, которые разработчики обещают исправить в ближайшее время.
А вот Safari вообще не поддерживает новый стандарт — так, все владельцы портативных девайсов от Apple не смогут оценить прирост производительности в приложениях.
Но стоит отметить, что команда Flutter обновила раннер для веб-приложений. Во время старта он проверяет возможности браузера и отображает либо js-версию, либо wasm skia, либо версию, полностью скомпилированную в wasm.
И отсюда — следующая проблема;
И без того «пухленькое» flutter приложение набрало еще больше веса. И теперь при холодном старте скачивается практически в 2 раза больше статических ресурсов в виде js-скриптов и wasm-модулей.
Очевидно, что этот процесс можно оптимизировать. Но мы пока этим не занимались;
Возможна только релизная сборка приложения в wasm.
Мы не можем разрабатывать в режиме сборки wasm, отладка/профилирование будет доступна только посредством браузера в релизном режиме;
Dart не дает возможности напрямую взаимодействовать с wasm-модулями. Для этого необходима js-прослойка.
Этот недостаток не позволяет использовать wasm за пределами js-среды
Несмотря на эти особенности, мы все же можем смело рекомендовать поэкспериментировать с вашими приложениями. Все полезные инструкции (для начала работы) лежат тут.
Больше полезного про Flutter — в Telegram-канале Surf Flutter Team.
Кейсы, лучшие практики, новости и вакансии в команду Flutter Surf в одном месте. Присоединяйтесь!