Егор Долгов
Егор Долгов
За все время: 723 просмотра, 355 посетителей.
За последние 30 дней: 41 просмотр, 14 посетителей.

Flutter 3.7: что нового?

Обновление Material 3, улучшенная производительность на iOS и многое другое!

2023 год начался с релиза новой версии Flutter 3.7: сообщество продолжает улучшать фреймворк, добавляя такие функции как возможность создания кастомизированных строк меню, каскадного меню, появились новые инструменты для поддержки интернационализации и исправления ошибок; также усовершенствовались функции выделения элементов global selection, скорость рендеринга при помощи Impeller, DevTools и вся производительность в целом.

Это перевод оригинальной статьи What’s new in Flutter 3.7

Улучшенная поддержка Material 3

В Версии 3.7 значительно расширилась поддержка Material 3 при помощи миграции следующих виджетов:

Чтобы использовать эти функции, просто включите флаг useMaterial3 в виджете ThemeData widget своего приложения. Чтобы в полной мере воспользоваться поддержкой M3, вам понадобится его полная цветовая схема. Вы можете создать свою собственную, используя новый инструмент создания тем или же Flutter может сгенерировать ее для вас из одного исходного цвета, используя параметр colorSchemeSeed в конструкторе ThemeData:

Чтобы подробнее узнать о поддержке Material 3 для Flutter,  перейдите по ссылке. Также можно ознакомиться с интерактивным демо, в котором показаны все новые возможности M3.

Новые возможности меню

Теперь вы можете создавать панель меню и каскадные контекстные меню при помощи Flutter. Для macOS, создайте панель меню при помощи виджета PlatformMenuBar, который определяет нативные строки меню, отображаемые macOS вместо Flutter.

Для всех остальных платформ вы можете определить  меню Material Design, которое предоставит каскадные строки меню (MenuBar) или автономные каскадные меню, запускаемые другим элементом пользовательского интерфейса (MenuAnchor). Эти меню полностью настраиваемые, а их пункты могут быть настраиваемыми виджетами; также для пунктов вы можете использовать новые виджеты MenuItemButton и SubmenuButton.

Анонс Impeller

Новый движок для рендера Impeller стал доступен для ознакомления на iOS в стабильном канале. Для большинства приложений производительность Impeller должна соответствовать или даже превосходить рендер Skia; что касается точности, то Impeller реализует все, кроме нескольких редкоиспользуемых крайних случаев. Ожидается, что он станет основным средством рендеринга для iOS в грядущем стабильном релизе, поэтому команда Flutter всегда рада отзывам пользователей на GitHub.

Несмотря на то, что Impeller должна удовлетворить все потребности в рендеринге практически всех существующих приложений Flutter, все еще существует несколько пробелов в охвате API. Некоторые из них указаны во Flutter wiki. Также пользователи могут заметить небольшие визуальные различия в рендеринге между Impeller и Skia, которые могут быть багами, о которых можно сообщить по ссылке.

Такой прогресс в разработке Impeller был бы невозможен без сообщества, в частности, пользователи GitHub  ColdPaleLightguoguo338JsouLiang и magicianA поспособствовали 37 патчам из 291 (>12%). Спасибо вам!

Команда Flutter продолжает работу над бэкендом Vulkan для Impeller (с откатом к OpenGL на старых устройствах), однако для предварительной версии для Android Impeller еще не готов. Поддержка Android находится в стадии активной разработки, и новости не только о ней, но и о поддержке настольных компьютеров и WEB ожидаются в последующих выпусках.

За прогрессом можно следить на доске проекта на GitHub.

Проверка релизов для iOS

При выпуске приложения для iOS, контрольный список настроек для обновления проверяет ваше приложения на готовность для размещения в App Store.

Команда flutter build ipa теперь может проверять некоторые из этих настроек и информировать разработчика о наличии нужных изменений для приложения перед его релизом.

Обновления DevTools

В этом релизе появилось несколько новых функций инструментов и общих улучшений, к примеру, полная переработка инструмента отладки памяти. Также появились три новые вкладки функций: «Profile», «Trace» и «Diff», которые поддерживают все ранее поддерживаемые функции отладки памяти и добавляют несколько новых. Они включают в себя возможность анализировать текущее распределение памяти для приложения по классам и типам памяти; исследовать, какие пути кода выделяют память для набора классов во время выполнения; сравнивать снимки памяти для понимания управления памятью между двумя точками во времени. Для более подробных деталей можно ознакомиться с документацией на docs.flutter.dev.

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

Это всего лишь пара основных моментов, но этот релиз содержит несколько исправлений ошибок и улучшений помимо функций, упомянутых здесь, в том числе некоторые важные исправления ошибок для Inspector, профилировщиков сети и ЦП. Чтобы получить более подробный список обновлений, ознакомьтесь с примечаниями к выпуску изменений DevTools, которые вошли во Flutter 3.7.

Настраиваемые контекстные меню

Теперь вы можете создавать собственные контекстные меню в любом месте приложения Flutter, а также использовать их для настройки встроенных контекстных меню.

Например, вы можете добавить кнопку «Отправить электронное письмо» на панель инструментов выбора текста по умолчанию, которая появляется, когда пользователь выделяет адрес электронной почты (код). См. параметр contextMenuBuilder, который был добавлен к существующим виджетам, отображающим контекстное меню по умолчанию, например TextField. Вы можете вернуть любой виджет по желанию из contextMenuBuilder, включая изменение контекстного меню по умолчанию, адаптированного к платформе.

Эта новая функция работает не только с текстовым выделением. К примеру, вы можете создать виджет Image, который будет показывать кнопку Save либо при нажатии на него правой кнопкой мыши, либо при долгом касании (код). Используйте ContextMenuController для отображения настраиваемого или дефолтного контекстного меню для текущей платформы в любом месте приложения.

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

Виджеты CupertinoListSection и CupertinoListTile

Благодаря стараниям пользователя GitHub Campovski, Cupertino получил два новых виджета,  CupertinoListSection и CupertinoListTile, для отображения прокручиваемого списка виджетов в стиле iOS. Это Cuperino-версии ListView и ListTile в Material.

Улучшения прокрутки

Прокрутка также получила обновления в этом релизе: более гладкое и усовершенствованное взаимодействие с трекпадом, новые виджеты Scrollbars и DraggableScrollableSheet и улучшенная обработка выделения текста в контексте прокрутки. Также приложения macOS будут обладать более высокой точностью благодаря новой физике прокрутки, соответствующей платформам ПК.

Кроме того, новые виджеты AnimatedGrid и SliverAnimatedGrid теперь могут анимировать элементы, добавленные в список или же удаленные из него.

Была исправлена регрессия в конструкторе билдера нескольких виджетов прокрутки, к примеру, ListView. Во время миграции NNBD фреймворка Flutter itemBuilder, который позволяет пользователям предоставлять виджеты по запросу, был перенесен в IndexedWidgetBuilder. Это означало, что itemBuilder больше не мог возвращать значение null, которое (в прошлом) можно было использовать для обозначения достижения конца списка. Этот функционал был восстановлен с помощью NullableIndexedWidgetBuilder. Спустя годы после миграции пользователь @rrousselGit заметил это и прислал исправление.

Инструмент интернационализации

Поддержка интернационализации получила обновление: инструмент gen-l10n был полностью переписан для поддержки:

Больше информации можно найти по ссылке.

Улучшения глобального выделения

SelectionArea теперь поддерживает выделение клавиатурой. Существующий выбор можно расширить при помощи клавиатурных сочетаний, например shift+right.

https://vimeo.com/792060738

Фоновые изоляты

Теперь Platform Channels можно вызывать из любого Isolate. Раньше пользователи могли сделать это только из основного изолята Flutter. Это упрощает работу с изолятами и кодом хост-платформы в плагинах или дополнениях к приложению. Для получения дополнительной информации ознакомьтесь с  этим разделом на сайте flutter.dev и подробной статьей об background isolate channels на Medium.

Текстовая лупа

Лупа, появляющаяся при выделении текста в Android и iOS, теперь работает и в приложениях Flutter. Эта функция включена по умолчанию для всех приложений с выделением текста и ее можно отключить или настроить в свойстве magnifierConfiguration.

Swift-миграция для плагинов

Поскольку Apple сосредоточились на Swift для своих собственных API, команда Flutter разработала ссылки для того, чтобы разработчики плагинов Flutter могли разрабатывать новые плагины со Swift или мигрировать старые. Плагин  quick_actions мигрировал из Objective-C на Swift и может демонстрироваться в качестве примера. Если вы хотите помочь в миграции плагинов 1P, ознакомьтесь с этим разделом на вики.

Ресурсы для iOS-разработчиков

Были опубликованы несколько новых ресурсов для разработчиков на iOS, включая:

Прекращение поддержки Bitcode 

Начиная с Xcode 14, bitcode больше не требуется для приложений watchOS и tvOS, и App Store больше не принимает предложения bitcode из Xcode 14, так что его поддержка была убрана из Flutter.

В приложениях Flutter bitcode выключен по умолчанию, что не должно помешать большинству разработчиков. Однако, если вы вручную включили bitcode в своем проекте Xcode, отключите его, как только обновитесь до Xcode 14. Это можно сделать, открыв ios/Runner.xcworkspace и сменив Enable Bitcode на No. Разработчики дополнений к приложениям могут сделать это в хост-проекте Xcode.

Узнать больше об этом обновлении можно в этой документации Apple.

iOS PlatformView BackdropFilter

Добавлена возможность размытия для нативного просмотра iOS при рендере под виджетом Flutter, и виджеты UiKitView теперь могут быть обернуты внутри BackdropFilter.

Больше информации можно узнать в документе.

Управление памятью

В этом релизе представлено несколько улучшений в управлении памятью, которые в совокупности снижают количество зависаний, вызванных паузами при сборке мусора, снижают загрузку ЦП из-за скорости выделения и фоновых потоков сборки мусора, а также уменьшают объем памяти.

Например, была расширена существующая практика ручного освобождения собственных ресурсов, поддерживающих определенные Dart объекты dart:ui. Раньше собственные ресурсы удерживались движком Flutter до тех пор, пока мусор виртуальной машины Dart не собирал объекты Dart. Анализируя пользовательские приложения и собственные тесты, разработчики определили, что эта стратегия в целом не позволяет избежать несвоевременных GC и чрезмерного использования памяти. Поэтому в этом выпуске движок Flutter добавляет API для явного освобождения собственных ресурсов, удерживаемых объектами Vertices, Paragraph и ImageShader.

Бенчмарки платформы Flutter, перенесенной на этот API, показали, что эти улучшения сократили время сборки кадра с 90% до более чем 30%, что конечные пользователи будут воспринимать как более плавную анимацию с меньшим количеством рывков.

Кроме того, движок Flutter больше не регистрирует размер изображений графического процессора с Dart VM. Как указано выше, эти изображения уже были вручную освобождены фреймворком при отсутствии необходимости, поэтому информирование политики Dart GC о размере памяти графического процессора, поддерживающего объекты кучи Dart, без необходимости увеличивало нагрузку на память кучи Dart, вызывая несвоевременные GC, которые не могли собрать ни какую дополнительную память. Аналогичным образом, теперь политика движка Flutter заключается в том, чтобы сообщать виртуальной машине Dart только небольшой размер нативных объектов, которые поддерживают Dart объекты dart:ui.

Тесты показывают, что это изменение устраняет синхронную работу GC при построении кадров, когда виджет создает резидентные изображения GPU.

В этом релизе Flutter Engine также лучше динамически обновляет виртуальную машину Dart информацией о состоянии приложения Flutter. В частности, Flutter теперь использует API Dart VM в стиле RAIL для перехода в режим с малой задержкой во время анимации перехода маршрута. В этом режиме с малой задержкой распределитель памяти Dart VM предпочитает увеличение кучи, а не сборку мусора, чтобы избежать прерывания анимации перехода с паузами GC. Хотя это изменение не привело к значительному повышению производительности, планируется расширение использования этой модели в будущих выпусках, чтобы устранить несвоевременные паузы при сборке мусора. Кроме того, были исправлены ошибки в логике, решающей, когда уведомлять виртуальную машину Dart о том, что движок Flutter простаивает. Исправление этих ошибок также предотвращает дерганье, связанное с сборщиком мусора. Наконец, для дополнений для приложений Flutter, механизм Flutter теперь информирует виртуальную машину Dart, когда интерфейс Flutter больше не отображается. Это приводит к тому, что виртуальная машина Dart инициирует финальную основную сборку мусора для изолята, связанной с интерфейсом. Это изменение уменьшает объем памяти Flutter, когда интерфейс Flutter не виден.

Прекращение поддержки macOS с 10.11 по 10.13

Как и было объявлено ранее, Flutter больше не поддерживает версии macOS 10.11 и 10.12. После этого объявления, последующий анализ показал, что прекращение поддержки 10.13 также ограничит дополнительное влияние и поможет значительно упростить кодовую базу. Это означает, что приложения, созданные для стабильных SDK Flutter в этом и последующих релизах, больше не будут работать на этих версиях macOS, и минимальной поддерживаемой версией станет 10.14 Mojave.

Как следствие, поскольку все версии iOS и macOS, поддерживаемые Flutter, включают поддержку Metal, серверная часть OpenGL была удалена из модулей iOS и macOS embedders. Удаление этих серверных частей уменьшило сжатый размер движка Flutter примерно на 100 КБ.

toImageSync

Этот релиз добавляет в dart:ui методы Picture.toImageSync и Scene.toImageSync, аналогично асинхронным методам Picture.toImage, и Scene.toImage.Picture.toImageSync синхронно возвращающие обработку в Image из Picture с растеризацией из Image, находящимся асинхронно на фоне. Затем изображение сохраняется как резидентное в графическом процессоре, когда доступен контекст графического процессора, а это означает, что его отрисовка выполняется быстрее по сравнению с изображениями, созданными toImage. (Изображения, созданные с помощью toImage, также могут оставаться резидентными в графическом процессоре, но эта оптимизация еще не реализована.)

Новые API toImageSync поддерживают такие случаи использования, как:

Быстрое выделение тяжелого для растеризации изображения для повторного использования в нескольких кадрах.
Применение многопроходных фильтров к изображению.
Применение пользовательских шейдеров.

Как пример, платформа Flutter теперь использует этот API для повышения производительности переходов между страницами на Android, что почти вдвое сокращает время растеризации кадров, уменьшает рывки и позволяет анимации достигать 90/120 кадров в секунду на устройствах, поддерживающих эту частоту обновления.

Улучшение поддержки настраиваемых шейдеров

Этот релиз включает в себя многочисленные улучшения поддержки Flutter для пользовательских фрагментных шейдеров. Flutter SDK теперь включает компилятор шейдеров, который компилирует шейдеры GLSL, перечисленные в файле pubspec.yaml, в правильный внутренний формат для целевой платформы. Кроме того, пользовательские шейдеры теперь можно перезагружать в горячем режиме для удобного цикла разработки. Пользовательские шейдеры также теперь поддерживаются бэкендами Skia и Impeller на iOS.

Сообщество уже поделилось демонстрационными примерами:

https://twitter.com/reNotANumber/status/1599717360096620544
https://twitter.com/reNotANumber/status/1599810391625719810
https://twitter.com/wolfenrain/status/1600242975937687553
https://twitter.com/iamjideguru/status/1598308434608283650
https://twitter.com/rxlabz/status/1609975128758026247
https://twitter.com/RealDevOwl/status/1528357506795421698
https://twitter.com/TakRutvik/status/1601380047599808513
https://twitter.com/wolfenrain/status/1600601043477401606

Ознакомьтесь с подробной документацией по написанию и использованию шейдеров и с полезным пакетом утилит flutter_shaders на pub.dev.

Горячая перезагрузка ассетов шрифтов

Раньше добавление новых шрифтов в файл pubspec.yaml требовало пересборки приложения для их просмотра, в отличие от других типов ресурсов, которые можно было перезагружать в горячем режиме. Теперь изменения в манифесте шрифтов, включая добавление новых шрифтов, можно перезагружать в приложение в hot reload.

Уменьшение рывков анимации на устройствах iOS

Благодаря вкладу с открытым исходным кодом от luckysmg, два улучшения уменьшили рывки анимации на iOS. В частности, добавление фиктивного CADisplayLink в основной поток во время жестов теперь приводит к обновлению с максимальной частотой. Кроме того, анимация клавиатуры теперь устанавливает частоту обновления CADisplayLink на ту же частоту обновления, которая используется аниматором движка Flutter. Благодаря этим изменениям пользователи должны заметить более плавную анимацию на устройствах iOS с частотой 120 Гц.

Итог

Как всегда, команда разработчиков Flutter благодарит участников сообщества за весь вклад, внесенный в развитие проекта. Без этого вклада Flutter не был бы таким замечательным, каким он является сейчас. Поскольку мы продолжаем это путешествие вместе, команда Flutter в Google хочет, чтобы вы все знали, что мы не смогли бы сделать это без вас. Спасибо!