Мы — команда Surf. По традиции представляем перевод официальной статьи про свежий релиз Flutter 3.3, дополненный нашими комментариями. Добро пожаловать во Flutter 3.3! Всего три месяца тому назад мы анонсировали Flutter 3: важнейший релиз, который включал поддержку основных платформ в стабильном канале. Хорошая новость в том, что с тех пор разработка только продолжила набирать обороты. С момента релиза Flutter 3 Flutter смёрджили 5 687 пул-реквестов. В этот релиз вошли обновления веб и десктопной версии Flutter, улучшения производительности при работе с текстом и многое. Мы также внесли долгожданные обновления в пакет go_router, DevTools и расширения VS Code. Подробнее обо всём — в статье. В традиционном веб-приложении можно выбрать несколько веб-элементов, протянув курсор, но в веб-приложении на Flutter так сделать было нельзя. Теперь это в прошлом: с появлением виджета SelectionArea любой дочерний элемент виджета SelectionArea можно выделять. Комментарий разработчика Александра Мартынова На данный момент поведение SelectionArea немного отличается от ожиданий, особенно это заметно в вебе. Во всех протестированных браузерах в контекстном меню отсутствовал пункт «Копировать», хотя это один из основных кейсов при работе с выделением. При этом, например, для виджета SelectableText он есть. И в вебе, и на десктопах не хватает привычного выделения по двойному и тройному клику мышкой.  Чтобы воспользоваться новой фичей, оберните тело роута (например Scaffold) в виджет SelectionArea: об остальном позаботится Flutter. Подробнее ознакомиться с этой крутейшей новинкой можно на странице SelectionArea API. Flutter 3.3 поддерживает ввод с трекпада. Таким образом пользователь получает не только более разнообразный и плавный контроль ввода, но и избегает определённых случаев, когда система может неверно интерпретировать его действия. Пример подобной ошибки в интерпретации можно посмотреть на странице «Как перетащить элемент UI» во Flutter cookbook. Проскрольте до конца страницы — там вы найдёте экземпляр DartPad. А дальше сделайте следующее: Уменьшите размер окна, чтобы в верхней части появилась полоса прокрутки. Наведите указатель на верхнюю часть окна. Проскрольте страницу с помощью трекпада. До установки Flutter 3.3 с помощью скролла на трекпаде можно было только перетащить элемент, так как Flutter обрабатывал сэмулированные общие события. После установки Flutter 3.3 с помощью скролла на трекпаде корректно скроллится список, так как Flutter отправляет данные о жесте «скролла», который не распознаётся карточками, но при этом распознаётся scroll view. Подробнее об этом можно почитать в диздоке  Flutter Trackpad Gesture, а также в следующих пул-реквестах на GitHub: PR 89944: Поддержка трекпад жестов во фреймворке PR 31591: Трекпад жесты на iPad PR 34060: Переустановка «Трекпад жесты в ChromeOS/Android» PR 31594: Трекпад жесты на Win32 PR 31592: Трекпад жесты на Linux PR 31593: Трекпад жесты на macOS Теперь Flutter поддерживает рукописный ввод в Scribble с помощью стилуса Apple Pencil на iPadOS. Фича по умолчанию доступна в CupertinoTextField, TextField и EditableText. Чтобы открыть доступ к фиче для конечных пользователей, обновитесь до Flutter 3.3. Чтобы расширить опции редактирования текста, в этом релизе появилась возможность получать детальную информацию об обновлении текста от TextInputPlugin платформы. Ранее TextInputClient передавал только новое состояние отредактированного объекта без значений, на которые новая версия отличается от старой, а TextEditingDeltas и DeltaTextInputClient заполнят этот пробел.  Доступ к данным об изменениях помогает создавать поля ввода с форматированными промежутками, которые расширяются и сжимаются, когда пользователь печатает. Подробнее об этом можно почитать в Rich Text Editor demo. Команда Flutter продолжает мигрировать всё больше компонентов Material Design 3 во Flutter. В этот релиз мы включили обновления IconButton, Chips, а также большую и среднюю версии AppBar. Комментарий разработчика Димы Шевченко В какой то момент на проекте мы столкнулись с проблемой: все стандартные IconButton изменили состояние нажатия. С одной стороны Material Design 3, это что-то новое и современное, с другой стороны — есть ощущение, что пользователи ещё долго будут привыкать к новому дизайну. Мы пока решили использовать привычные стейты. Следить за миграцией Material Design 3 можно в Bring Material 3 to Flutter на GitHub. Ранее версия десктопного приложения для Windows устанавливалась в индивидуальном файле Windows-приложения. Такое поведение отличалось от того, как версии устанавливались на других платформах. Теперь версии десктопных приложений для Windows можно установить в файле pubspec.yaml и аргументах сборки. Так станет легче установить автообновления для конечных пользователей, чтобы они получали крутые новинки, как только вы запушили обновление приложения. Подробнее об установке версии приложения можно прочитать в документации на docs.flutter.dev и в руководстве по миграции. Проекты, созданные до Flutter 3.3, необходимо обновить, чтобы фича заработала. Разрабатывать приложения со сложной навигацией довольно непростая задача. Чтобы расширить API нативной навигации во Flutter, наша команда опубликовала новую версию пакета go_router. С ней станет проще разрабатывать навигацию для сервисов, которые есть в мобильном, десктопном и веб-представлении. Пакет go router поддерживается командой Flutter и делает разработку навигации проще благодаря декларативному API на основе url: это облегчает навигацию и работу с диплинками. Свежая версия (4.3) позволяет приложениям выполнять редирект с помощью асинхронного кода, а также включает другие изменения без обратной совместимости, описанные в руководстве по миграции. Подробнее об этом можно почитать на странице Навигация и роутинг на docs.flutter.dev. Комментарий разработчика Федора Благодырь Зачастую в приложениях необходимо использовать несколько стаков навигации (табы, drawer и так далее). Go_router пока еще не имеет такой функциональности из коробки: есть открытый PR, но ещё не слитый.  Считаю, что пока нет возможности сохранять состояния в табах и описывать роутинг хотя бы на 50% так же просто, как в auto_route: он давно предлагает такую функциональность и даёт возможность гибко настраивать поведение. Но мне нравится, что go_router ведётся Гуглом: это весомо.  У расширения Visual Studio Code для Flutter появился ряд обновлений: в том числе легче стало добавлять зависимости. Теперь можно добавлять несколько зависимостей, отделённых запятой, в один шаг с помощью Dart: Add Dependency. Подробнее о том, как мы усовершенствовали расширение Visual Studio Code с последнего стабильного релиза Flutter, можно прочитать здесь: VS Code расширения v3.46 VS Code расширения v3.44 VS Code расширения v3.42 В DevTools появилось сразу несколько обновлений с последнего стабильного релиза Flutter, включая улучшения UX и производительности при отображении таблиц данных, что позволит быстрее и плавнее скроллить большие списки событий (#4175). Полный перечень обновлений с Flutter 3.0 можно найти в отдельных анонсах по ссылкам: Flutter DevTools 2.16.0 пометки к релизу Flutter DevTools 2.15.0 пометки к релизу Flutter DevTools 2.14.0 пометки к релизу Повысилась производительность при загрузке изображений из ассетов: мы сократили число копий и сбавили обороты при сборе мусора (garbage collection — GC) в Dart. Раньше, при загрузке изображений из ассетов, ImageProvider API требовал многократно копировать сжатые данные. Сначала — в нативную динамическую память, когда ресурс открывался и данные предоставлялись Dart в виде массива типизированных данных. Затем — второй раз, когда этот самый массив типизированных данных копировался во внутреннее хранилище ui.ImmutableBuffer. С появлением ui.ImmutableBuffer.fromAsset байты сжатого изображения можно загрузить непосредственно в структуру, используемую для декодирования. Этот подход требует изменить процесс загрузки байтов в ImageProviders. Такая процедура к тому же быстрее: позволяет избежать затраты ресурсов на дополнительное распределение задач, которое требовалось для предыдущего лоудера, работавшего на основе method channel. Так, скорость загрузки изображения сократилась почти в два раза в ходе наших микробенчмарк-тестов. Подробнее ознакомиться с этой темой и руководством по миграции можно в Adding ImageProvider.loadBuffer на docs.flutter.dev. В стабильном релизе 2.10 мы добавили оптимизацию сжатия указателей Dart на iOS. Однако Yeatse с GitHub предупредил нас о непреднамеренных последствиях такой оптимизации. Сжатие указателей в Dart происходит благодаря резервированию большого объема виртуальной памяти для динамической памяти Dart. Так как общий объём виртуального хранилища, разрешённый на iOS, меньше, чем на других платформах, такой громоздкий резерв сокращает объем памяти, доступной другим компонентам, которые тоже резервируют память, например, Flutter-плагинам. Несмотря на то, что отказ от сжатия указателей увеличивает объем памяти, занимаемой объектами Dart, он также увеличивает объём памяти, доступной для частей Flutter-приложения, не связанных с Dart, что в целом предпочтительнее. Apple даёт разрешение, с которым можно увеличить максимальный доступный объём виртуальной памяти приложения, однако такое разрешение поддерживается только новыми версиями iOS и не будет работать на устройствах с версиями iOS, которые всё ещё поддерживаются во Flutter. Когда это разрешение можно будет использовать везде, мы планируем вернуться к оптимизации. В предыдущих релизах нужно было вручную настраивать кастомную Zone, чтобы выловить все exception и error приложения. Однако кастомные Zone наносили ущерб ряду оптимизаций в базовых библиотеках Dart, замедляя запуск приложения. В этом релизе вместо кастомных Zone вылавливать ошибки следует с помощью колбека PlatformDispatcher.onError. Подробнее об этом можно почитать на обновлённой странице Работа с ошибками во Flutter на docs.flutter.dev. Фрагментные шейдеры, написанные в GLSL и перечисленные в разделе shaders: манифеста Flutter в файле pubspec.yaml , теперь будут автоматически компилироваться в корректный формат, понятный для движка, и объединяться в бандл с приложением в виде ассета. Благодаря этому изменению больше не придётся вручную компилировать шейдеры с помощью сторонних инструментов.  В будущем советуем исходить из того, что FragmentProgram API движка может принимать только то, что поставляет Flutter-сборщик. Пока этого ещё не произошло, но изменение запланировано на следующий релиз, что указано в диздоке Улучшенная поддержка FragmentProgram API. С примером изменения можно ознакомиться здесь: пример шейдера во Flutter. Раньше движок Flutter постоянно выравнивал составляемые слои точно по границам пикселей, потому что так он улучшал производительность отрисовки на старых (32-битных) моделях iPhone. Когда появилась поддержка десктопов, мы заметили, что такое поведение давало заметную привязку цифровых пикселей к аналоговым (pixel snapping), так как соотношение логических и физических пикселей на устройстве (screen device pixel ratio —DPR), как правило, сильно ниже. К примеру, на экранах с низким DPR это особенно было заметно на подсказках.  Как только мы определили, что такое поведение больше не требовалось для улучшения производительности на новых моделях iPhone, мы избавились от него в движке Flutter, чтобы улучшить качество изображения на десктопах. Помимо того, мы обнаружили, что, убрав pixel snapping, мы стабилизировали результаты в ряде внутренних golden-тестов изображений, которые часто менялись с минимальной разницей в отрисовке. Как мы уже анонсировали ранее в стабильном релизе 3.0, предыдущий релиз был последним с поддержкой 32-битных iOS-устройств и версий iOS 9 и 10 из-за снижения популярности. Изменение затрагивает iPhone 4S, iPhone 5, iPhone 5C, а также 2, 3 и 4 поколение iPad.  Стабильная версия Flutter 3.3 и все следующие стабильные релизы больше не будут поддерживать 32-битные iOS устройства и версии iOS 9 и 10. Это значит, что приложения, написанные во Flutter 3.3 и следующих версиях, не будут запускаться на таких устройствах. В стабильном релизе 4 квартала 2022 года мы планируем прекратить поддержку macOS версий 10.11 и 10.12. Это значит, что приложения, написанные на стабильных Flutter SDK после этого момента больше не будут работать на этих версиях. Минимальной версией macOS, которую поддерживает Flutter, станет 10.13 High Sierra. Bitcode больше не будет приниматься для iOS приложений в ближайшем релизе Xcode 14. Проекты, где разрешён bitcode, будут эмитить предупреждение при сборке в этой версии Xcode. Flutter прекратит поддержку bitcode в следующем стабильном релизе. По умолчанию Flutter-приложения не разрешают использовать bitcode, и мы предполагаем, что это изменение не помешает множеству разработчиков. Тем не менее, если вы вручную разрешили использование bitcode в Xcode-проекте, отмените его, как только обновитесь до Xcode 14.  Чтобы это сделать, откройте ios/Runner.xcworkspace и в настройке Enable Bitcode выберите No. Разработчикам, которые добавляют элементы Flutter в нативное приложение, следует отключить его в основном Xcode-проекте. В документации Apple можно подробнее почитать о дистрибутивах с bitcode. Мы каждый раз это говорим, но команда Flutter в Google невероятно благодарна сообществу за ту поразительную работу, которую оно проделывает, чтобы Flutter стал именно таким замечательным, как сейчас. Надеемся поскорее вернуться к работе и улучшить то, что мы уже сделали, концентрируясь на самом важном — на всех вас. Больше полезного про Flutter — в телеграм-канале Surf Flutter Team. Публикуем кейсы, лучшие практики, новости и вакансии Surf, а также проводим прямые эфиры. Присоединяйтесь! Больше кейсов команды Surf ищите на сайте >>