О чём говорили на конференции Flutter Forward в Найроби: перевод статьи с комментариями разработчиков Surf

Flutter Forward — мероприятие для разработчиков со всего мира: они собираются онлайн и офлайн, чтобы узнать о том, как будет развиваться Flutter в будущем. 

Давайте разберём улучшения, которые мы планируем внести во Flutter. Мы хотим:

  • добиться революционной производительности графического движка,

  • добиться бесшовной интеграции для веб и мобильных платформ, 

  • ввести начальную поддержку для новых и развивающихся архитектур, 

  • а также уделять постоянное внимание опыту разработчиков. 

Сегодня мы рассказываем о работе, которую постепенно проделаем в течение следующих месяцев. 

Сразу оговоримся: фичи, которые мы показываем, находятся в разработке и ещё могут существенно измениться.

Революционно высокая производительность графического движка

Когда речь заходила о графике, кроссплатформенные фреймворки всегда требовали компромиссов. Во Flutter есть свой собственный слой отрисовки, благодаря которому разработчик получает аппаратно ускоренную графику и добивается единообразия приложений на всех устройствах.

Impeller

В будущем мы планируем вывести производительность графического движка на принципиально новый уровень. Мы демонстрируем прогресс в работе над Impeller — графическим движком нового поколения для Flutter. Impeller оптимизирован под Flutter: это даёт больше пространства для манёвров и контроля над графическим конвейером.

Impeller обеспечивает более предсказуемую работу приложения: благодаря заранее скомпилированным шейдерам он нивелирует пропуск кадров в рантайме, возникающий из‑за их компиляции. Также он пользуется преимуществами примитивов в Metal и Vulkan, современных низкоуровневых API в iOS и Android. А ещё он грамотно использует параллелизм, распределяя задачи одного кадра по разным потокам.

Impeller обеспечивает идеально гладкую работу приложений со сложной графикой вроде Wonderous. Это очень красивое приложение, в котором можно посмотреть все чудеса света.

Последняя версия Wonderous, в которой UI подстраивается под различные устройства и форм-факторы. Приложение можно скачать на https://wonderous.app
Последняя версия Wonderous, в которой UI подстраивается под различные устройства и форм-факторы. Приложение можно скачать на https://wonderous.app

Помимо идеально гладкой работы UI, Impeller способен изрядно улучшить производительность в определённых сценариях.

На видео ниже показан отличный пример такого случая.

Слева — приложение калейдоскопа, которое использует кадрирование SVG и отрисовано текущим дефолтным средством отображения. Если проскроллить страницу вниз, производительность падает: отрисовка отнимает больше, чем заложено в покадровый бюджет. В результате получаем частоту 7–10 кадров в секунду.

Справа — то же приложение, но на Impeller, который рисует 60 кадров в секунду без глитчей.

Комментарий разработчиков Surf

Мы уже протестировали Impeller на нескольких проектах и рады официально сообщить, что эра джанков на iOS подходит к концу! Даже в случаях, когда мы сталкивались с катастрофическими показателями профилировщика и длительностью кадров в полсекунды, Impeller показал себя крайне эффективным. Результаты даже превзошли ожидания — по сравнению с предварительным прогревом SkSL‑шейдеров.

Отмечается, что Impeller рендерит интерфейс иначе, и это уже заметно сейчас. Исчезли некоторые классические проблемы Skia, такие как «зазоры» между UI‑элементами, которые находятся близко друг к другу: это часто выражается в виде белых полосок на экране.

Тем не менее, следует учитывать, что движок всё ещё находится в статусе «превью». Судя по всему, он пока не может справиться с рендерингом некоторых классических виджетов. Например, в одном из наших приложений с большим количеством анимаций интерфейс просто сломался из‑за использования виджета Transform.

Поддержка кастомных шейдеров

Архитектура Flutter способна поддерживать абсолютно новые юзкейсы. Недавно вышла поддержка кастомных шейдеров — и она уже появляется в новых крутых демо, где показана бесшовная интеграция с иерархией виджетов Flutter.

Отметим, что дело не ограничивается мобильными устройствами: теперь у нас появилась начальная поддержка кастомных шейдеров и в веб. Одна и та же кодовая база теперь обеспечивает работу аппаратно ускоренных интерфейсов как на iOS и Android, так и в браузере.

Теперь Flutter поддерживает пиксельные шейдеры в веб, а значит уже можно применять кое-какие крутые визуальные эффекты. Автор: Erick Ghaumez
Теперь Flutter поддерживает пиксельные шейдеры в веб, а значит уже можно применять кое-какие крутые визуальные эффекты. Автор: Erick Ghaumez

Поддержка 3D

Также мы приступаем к первым этапам работы над поддержкой 3D. Во вступительной речи мы показали, как можно импортировать модели, созданные в Blender, и даже использовать hot reload, чтобы выполнять итерации в Blender в реальном времени и видеть результаты в запущенном приложении.

Мы пока только начали, но первые показатели производительности уже воодушевляют — как и потенциальная возможность интегрировать 3D в другие интерфейсы на Flutter.

Благодаря Impeller во Flutter можно рендерить 3D-графику, как показано на этой демке с Дэшем
Благодаря Impeller во Flutter можно рендерить 3D-графику, как показано на этой демке с Дэшем

Комментарий разработчиков Surf

Многие считают, что 3D-графика в мобильных приложениях нужна только для игр. Но это не так: 3D используется во многих обычных приложениях для улучшения интерфейса и повышения удобства использования. Например, 3D-модели могут помочь при создании дополненной реальности, визуализации интерьеров и экстерьеров, создании трёхмерных диаграмм и графиков и во многом другом.

Совсем недавно мы разрабатывали проект с интеграцией 3D. Поскольку предполагалось не просто отображение 3D модели, но также сложное освещение, тени и физика, мы пришли к рациональному решению реализации 3D-объекта на нативе с использованием SceneKit (iOS) и SceneView (Android). 

Появление поддержки, как минимум, существенно упростит задачу интеграцию простых 3D-объектов во Flutter-приложение и сделает отображение 3D объектов на разных платформах более консистентным. 

С появлением 3D и кастомных шейдеров планка производительности графического движка в межплатформенных тулкитах для разработки UI поднялась на новый уровень. Нам не терпится посмотреть, как вы примените новые фичи, когда они появятся в доступе.

Бесшовная интеграция с веб- и мобильными платформами

Приложение, конечно, можно полностью написать на Flutter и Dart. Но почти любой более‑менее сложный проект потребует связать Dart код с другим видом кода. В веб Flutter можно использовать в качестве компонента, встроенного в приложение помасштабнее. На мобильных устройствах приложениям бывает нужно обратиться к системным API или коду, написанному на другом языке.

Поэтому вторая область, которой мы планируем посвятить время и силы, — это бесшовная интеграция для веб и мобильных платформ.

Интеграция с веб

Мы готовы продемонстрировать новую фичу element embedding. Благодаря ей контент на Flutter можно добавить в любой стандартный веб <div>. Так Flutter становится обычным веб‑компонентом, бесшовно интегрируется в веб DOM и даже даёт возможность использовать CSS‑селекторы и трансформации, если нужно форматировать родительский объект Flutter.

Также мы вносим существенные изменения в пакет js, чтобы обеспечить бесшовное сопряжение JavaScript и Dart‑кода. С помощью js можно аннотировать любую функцию в Dart коде с помощью атрибута @JSExport, а затем вызвать её из своего JavaScript кода.

В совокупности две этих фичи открывают новые захватывающие сценарии работы с Flutter в веб. В концептуальном демо, которое мы показали на Flutter Forward, представлено простое Flutter‑приложение, встроенное в веб‑страницу на HTML.

С помощью CSS мы применяем анимированный эффект вращения — с Flutter‑контентом можно взаимодействовать даже в движении. Также в демо видно, что с помощью HTML‑кнопки и обработчика событий JavaScript можно вносить изменения в состояние Flutter и наоборот. Мы считаем, что по завершении этого проекта появится много новых способов добавлять интерактивные элементы Flutter в уже существующие веб‑приложения.

С помощью element embedding можно встраивать Flutter в <div> элемент и форматировать его с помощью CSS
С помощью element embedding можно встраивать Flutter в <div> элемент и форматировать его с помощью CSS

Интеграция с мобильными платформами

Flutter уже давно поддерживает интеграцию с системными API с помощью платформенных каналов: в них доступна коммуникация с кодом на языках вроде Kotlin или Swift на основе сообщений (message‑based approach). Таким образом действительно можно получить доступ к библиотекам. Но нужно, чтобы автор приложения был знаком с несколькими языками, а также написал солидное количество бойлерплейта.

Сейчас мы приступаем к работе над новым подходом к сопряжению систем, который бы позволил вызывать библиотеки напрямую. На iOS мы взяли за основу работу, проделанную над FFI для сопряжения с языком C, с поддержкой библиотек Swift и Objective‑C. На Android с помощью JNI мы выстраиваем мост к библиотекам Jetpack, написанным на Kotlin.

С помощью новой команды Dart автоматически создаёт связки для межъязыковых сопряжений и соответствующей конвертации классов данных. По завершении мы надеемся, что проделанная работа поможет Flutter‑разработчикам вызывать новые Jetpack или iOS‑библиотеки без использования плагинов или необходимости изучать другой синтаксис API, а также существенно облегчит работу авторам плагинов. Чтобы узнать больше, посмотрите на этот пример!

Комментарий разработчиков Surf

Один из самых частых вопросов от наших клиентов: «Можем ли мы реализовать {$feature_name} на Flutter?» За 4 года во Flutter‑разработке мы выработали универсальный ответ на этот вопрос: «Если мы можем это реализовать в нативе, значит, мы можем реализовать это и на Flutter».

Да, не всегда это имеет смысл — как в случае с какими‑нибудь замороченными фичами типа AR. Но технические реализуемо всё что угодно. Во многом именно платформенные каналы открывали нам практически безграничные возможности.

Однако платформенные каналы, невзирая на их гибкость, трудно назвать элегантными или даже удобными. Мало кому понравится вызывать платформенные методы, передавая их наименование обычной строкой в прямо в канал. Да и типобезопасными их назвать сложно.

Поэтому тенденция на «бесшовность» нас однозначно радует. И если за @JSExport мы пока радуемся со стороны, то FFIgen и JNIgen — это то, что помогает нам уже сейчас. Очень радует, что Flutter целенаправленно развивается из состояния «этим можно пользоваться» в состояние «этим хочется пользоваться».

Начальная поддержка новых и развивающихся архитектур

Flutter можно запускать на разнообразных устройствах и в различных форм‑факторах — это возможно благодаря обширной поддержке широкого спектра процессорных архитектур в Dart, а также его хорошо оптимизированному JavaScript‑компилятору.

Однако, учитывая новые интересные возможности, появившиеся на горизонте, третьей областью будет начальная поддержка новых и развивающихся архитектур.

WebAssembly

WebAssembly — бинарный формат инструкций, не привязанный к конкретной платформе. С каждым годом он становится более зрелым: всё больше современных браузеров его поддерживает. Что крайне интересно, WebAssembly открывает доступ к веб‑платформе и другим языкам — помимо JavaScript.

Последние нескольких месяцев мы совместно с командой Chrome и другими партнёрами WebAssembly работали над начальной поддержкой для языков с автоматическим управлением памятью вроде Dart. Это расширение для WebAssembly уже поддерживается: есть флаг в последних сборках Chrome для разработчиков.

На Flutter Forward мы презентуем начальную поддержку Flutter‑компиляции в WebAssembly: это создаст условия для дальнейшей оптимизации скорости и размера при поддержке веб‑платформы.

RISC-V

Ещё одна платформенная архитектура, привлекающая всё больше интереса, — RISC‑V: открытая и свободная система команд и процессорная архитектура, разработанная для широкого применения.

Команда Android недавно выступила с речью о работе над поддержкой RISC‑V. Теперь и мы рады сообщить, что Dart поддерживает RISC‑V. Это наш шаг на пути к запуску Flutter приложений на RISC‑V устройствах, когда такие появятся в доступе.

Серийные изделия RISC‑V пока что находятся в зачаточном состоянии, но на Flutter Forward мы продемонстрировали, что уже смогли сделать на ClockworkPi DevTerm Kit R-01, модульном портативном Linux‑терминале.

Мы считаем, что поддержка RISC‑V будет особенно интересна в контексте встроенных технологий, где Flutter способен предложить мощный тулкит для разработки UI, отвечающий самым разным потребностям.

ClockworkPi DevTerm R-01, экспериментальный RISC-V компьютер, на котором запущено консольное приложение на Dart
ClockworkPi DevTerm R-01, экспериментальный RISC-V компьютер, на котором запущено консольное приложение на Dart

Комментарий разработчиков Surf

Знаете эти концепт-кары, которые очень красивые и футуристичные, но пока ещё никуда не едут? Если вы поняли, что новость о портировании Flutter на RISC-V вам ни о чём не говорит, – вы смотрите как раз на такой концепт-кар. Простым смертным значение этого шага пока оценить сложно: пока это только демонстрация возможностей, ещё один шаг на пути к тотальной кроссплатформенности. 

Чего не скажешь о поддержке WebAssembly: этот низкоуровневый язык уже сейчас поддерживается всеми современными браузерами. Что даст эта поддержка Flutter-разработчикам? Пока сложно сказать однозначно. Одна из центральных идей WASM – повышенная производительность. 

В 2019 году вышла научная статья «Not So Fast: Analyzing the Performance of WebAssembly vs. Native Code», авторы которой провели ряд бенчмарков и выявили, что WASM в среднем быстрее JS на 30%, но с массой нюансов. Есть ли ощутимый профит в контексте Flutter-разработки, мы пока не знаем.

Продолжаем развивать опыт разработчиков 

В канале разработки теперь добавилась начальная поддержка records и patterns — двух новых улучшений, которые особенно хорошо работают вместе.

Простой пример использования records и patterns, чтобы возвращать и получать несколько параметров функции
Простой пример использования records и patterns, чтобы возвращать и получать несколько параметров функции

Комментарий разработчиков Surf

Кстати, мы сделали подробный разбор этой фичи языка в одном из последних выпусков Flutter Dev Podcast. Приятного прослушивания!

Также мы формально анонсируем Dart 3. Он стал кульминацией нашей работы над внедрением sound null safety в язык. Кроме того, из Dart 3 ушли фичи, давным давно получившие статус deprecated. Мы уже начали публиковать альфа‑версии сборок Dart 3, а также соответствующие сборки Flutter, так что разработчики уже могут начать тестировать пакеты и приложения. Подробнее о Dart 3 можно почитать в отдельном посте на канале Dart.

И конечно же мы вкладываемся и в улучшение опыта разработки во Flutter. Тулкит для создания казуальных игр, которые мы анонсировали на I/O в прошлом году, оказался так популярен, что теперь мы анонсируем первую версию тулкита для новостного контента. Он ускоряет мобильную разработку для СМИ и других поставщиков контента, которым хотелось бы взаимодействовать с пользователями мобильных устройств, не собирая при этом своё собственное приложение с нуля.

В этот тулкит входит всё необходимое для разработки приложения со статьями, включая навигацию и поиск, аутентификацию, интеграцию рекламы, уведомления, профили и подписки. При этом он использует все лучшие практики из исследования Google News Initiative.

Сегодня с нами в Африке три разработчика, которые одними из первых пишут приложения на основе этого тулкита. Среди таких приложений Hespress, один из крупнейших новостных сайтов в Морокко, Bold Sports, популярный нигериский веб‑сайт, посвящённый спорту, а также The Standard, старейшая газета в Кении.

Движемся вперёд вместе

Надеемся, что вас так же сильно, как и нас, радует будущее, которое мы обрисовали для Flutter. Мы продолжаем уделять основное внимание ключевым аспектам разработки и в то же время вносим фундаментальные изменения, благодаря которым мы вместе с другими разработчиками сможем создать что‑то ещё более масштабное при помощи Flutter.

Помимо нашей собственной разработки, приятно наблюдать, как расширяется экосистема Flutter. Например, FlutterFlow — это решение для лоу-код разработки нативных мобильных приложений. Widgetbook позволяет дизайнерам и разработчикам совместно работать над пользовательским интерфейсом с помощью универсального тулинга.

Присоединяйтесь к каналу Surf Flutter Team в телеграме: там мы публикуем новости, вакансии, кейсы из нашей практики и другие полезности о разработке на Flutter. 

Присоединиться >>

Комментарии (12)


  1. beduin01
    00.00.0000 00:00

    Какие State менеджеры позволяют максимально сократить объем кода и писать вместо двух классов один? GetX к сожалению больше не поддерживается.


    1. neoxack
      00.00.0000 00:00
      +2

      Mobx


    1. rafuck
      00.00.0000 00:00

      Откуда информация о том, что getx не поддерживается?


      1. beduin01
        00.00.0000 00:00

        Два месяца назад у них в issues висела эта тема. Буду рад если проект будет жить.

        P.S. Посмотрел только что -- вижу на минувшей неделе появились новые коммиты.


    1. Daseron
      00.00.0000 00:00
      +3

      Riverpod?


      1. PackRuble
        00.00.0000 00:00

        Мне тоже нравится этот вариант в некоторой степени. Но без должной сноровки может сильно развязать руки))


        1. Daseron
          00.00.0000 00:00

          Можно поподробнее? Просто интересно стало.


          1. PackRuble
            00.00.0000 00:00
            +1

            Riverpod действительно может сократить код, но если не придерживаться чёткого архитектурного решения, то всё превратится в тыкву и будет Circular dependencies. Тот же bloc имеет некоторые паттерны, объясняющие, как его нужно использовать.


    1. Gorniv
      00.00.0000 00:00

      Странный подход к выбору State Managment, выбирать нужно от задач гибкости решения, я рекомендую работать с BLoC, а для кодо-генерации использовать https://marketplace.visualstudio.com/items?itemName=gornivv.vscode-flutter-files с custom template под свой проект.


      1. beduin01
        00.00.0000 00:00
        +1

        А почему странный? Я реально так и не понял зачем нужно два класса, когда можно одним обойтись. Получается код ради когда.


        1. Pasher
          00.00.0000 00:00

          В BLoC есть очень удобный Cubit. Если речь о простых типах данных, то в один класс все умещается


  1. PackRuble
    00.00.0000 00:00
    +2

    Честно говоря, с Wonderous они перемудрили. 6гб озу, snap 845. С этими вводными я вижу лаганое свистоперделочное приложение, в котором глаза вытекают от всех крученых-перекрученых анимаций с периодическими лагами при прогрузке новых маршрутов/зон. Я не могу понять, что оно демонстрирует?

    За перевод и личное мнение спасибо!