Flutter Web на WASM в 2026: в каких браузерах заказчика он запустится
Flutter Web с WASM в 2026 году работает в Chrome, Edge, Firefox и Яндекс Браузере на свежем движке, а всем остальным отдаёт запасную JavaScript-сборку. Её Flutter подставляет сам, если собрать проект с флагом --wasm. Проблемы возникают в трёх местах: старые браузеры на Windows 7, Safari на iOS и пакеты, которые тянут dart:html.
🧩 Что на самом деле собирает флаг --wasm
Частое заблуждение звучит так: включили --wasm, и приложение целиком переехало на WebAssembly. На деле команда flutter build web --wasm кладёт в папку сборки две версии. Одну собирает dart2wasm, другую dart2js. При открытии страницы загрузчик Flutter проверяет браузер и выбирает подходящую.
Вместе с компилятором меняется отрисовка. WASM-версия рисует через skwasm, JavaScript-версия через CanvasKit. Оба движка построены на Skia, но по-разному загружаются и по-разному работают с потоками. Поэтому тестировать нужно обе ветки, а не ту, которую вы видите на своём ноутбуке.
Условие для WASM-ветки одно: браузер должен поддерживать WasmGC, то есть сборку мусора внутри WebAssembly. Это Chrome и Edge начиная с версии 119, Firefox начиная с 120. Яндекс Браузер строится на Chromium и подходит, пока его движок свежий. В стабильный канал Flutter эта сборка попала в версии 3.22, в мае 2024 года.
🖥️ Кто откроет WASM-версию, а кто получит запасную
Понедельник, утро, у компании запускается новый портал заказов. Менеджеры в свежем Chrome говорят, что он летает. Бухгалтерия сидит на Windows 7, а для неё последний доступный Chrome имеет версию 109, и WasmGC там нет. Проект собран с --wasm, поэтому разработчики считают, что всё быстро. Но бухгалтерии достаётся запасная JavaScript-сборка, и на слабом компьютере она стартует заметно дольше. Сценарий типовой для компаний, где часть рабочих мест годами не обновлялась.
Группы браузеров заказчика и то, что получает каждая:
| Окружение | Поддержка WasmGC | Что получит пользователь | Что проверить до релиза |
|---|---|---|---|
| Chrome и Edge от 119, Яндекс Браузер на свежем Chromium | Да | WASM-сборка, отрисовка через skwasm | Заголовки сервера для многопоточности |
| Firefox от 120 | Да | WASM-сборка | Ввод текста, прокрутку и кириллицу в шрифтах |
| Chrome 109 на Windows 7 и 8.1 | Нет | Запасная JavaScript-сборка с CanvasKit | Время первой загрузки на слабом компьютере |
| Safari и любые браузеры на iPhone | Зависит от версии iOS и Flutter | Одна из двух веток, узнаете только на устройстве | Реальный iPhone вместо эмулятора |
| Android WebView на старых терминалах сбора данных (ТСД) | Зависит от версии WebView | Запасная JavaScript-сборка, если WebView не обновляется | Версию WebView на каждом терминале |
Запасная сборка работает, и в этом сила подхода: белого экрана на Windows 7 не будет. Слабое место в другом. Пока вы не прогнали обе ветки на реальных устройствах, вы не знаете, как приложение поведёт себя у бухгалтерии и на складе.
🔒 Заголовки сервера: многопоточность требует изоляции
Skwasm умеет работать в нескольких потоках, и тяжёлые экраны со списками заказов и отчётами отрисовываются плавнее. Для этого браузеру нужна изоляция страницы. Сервер отдаёт заголовок Cross-Origin-Opener-Policy со значением same-origin и заголовок Cross-Origin-Embedder-Policy со значением credentialless или require-corp. Без них приложение запустится, но в одном потоке.
У изоляции есть цена. Страница с такими заголовками перестаёт свободно грузить чужие ресурсы: картинки, скрипты и шрифты с других доменов без разрешающих заголовков браузер блокирует. Платёжную форму или карту в iframe придётся проверять отдельно. Если включить заголовки на основном домене компании, сломаются счётчики и виджеты сайта, а виноватым окажется Flutter.
Рабочий вариант: приложение живёт на отдельном поддомене, например app.company.ru, заголовки стоят только там, сторонних виджетов на нём нет. Если без чужих скриптов не обойтись, оставьте приложение в одном потоке. Оно всё равно остаётся на WASM-ветке.
📦 Пакеты: сборка падает раньше, чем доходит до браузера
Чаще всего WASM откладывают не из-за браузера, а из-за зависимости. Компилятор dart2wasm не принимает код, который импортирует dart:html, dart:js, dart:js_util или package:js. Вместо них нужны package:web и dart:js_interop. Сборка с --wasm остановится на таком импорте и покажет, в каком пакете он лежит.
Первыми под удар попадают плагины, которые обращаются к браузерному API: камера и сканер штрихкодов, загрузка и скачивание файлов, печать, просмотр PDF. Для B2B-портала это рабочие функции: менеджер прикладывает скан договора, бухгалтер скачивает акт. Если пакет не переведён на package:web, остаётся обновить его, заменить аналогом или обернуть нужный вызов своим кодом.
Заменить пакет на старте проекта проще, чем после релиза, когда на нём уже держится рабочий сценарий. Поэтому список зависимостей мы просматриваем до первой строки кода.
🌐 CanvasKit и шрифты: откуда они загружаются
В запасной JavaScript-ветке Flutter по умолчанию тянет CanvasKit с серверов Google, запасные шрифты тоже оттуда. Дома это незаметно. В корпоративной сети с фильтрацией трафика или на слабой мобильной связи запрос к чужому серверу задерживает первый экран, а вместо кириллицы на странице могут появиться квадраты.
Лечится двумя правками: собирать проект с ключом --no-web-resources-cdn, чтобы CanvasKit лежал рядом с приложением, и подключить нужные шрифты в assets. Шрифты добавят вес сборке, зато поведение перестанет зависеть от чужого сервера. Приложение открывают каждый день, поэтому браузер быстро закэширует эти файлы.
🎯 Когда WASM не нужен совсем
WASM помогает на тяжёлых экранах: большие таблицы, графики, анимации. Если у вас закрытый кабинет на двадцать менеджеров с формами и списками, выигрыш там заметить сложно, а расходы на заголовки, поддомен и проверку пакетов остаются. Запасная JavaScript-сборка, которую вы всё равно обязаны проверить, закрывает такую задачу сама.
Второе ограничение относится ко всему Flutter Web, а не только к WASM: приложение рисуется на canvas, и поисковики видят его хуже обычной вёрстки. Для личного кабинета за логином это безразлично. Публичный каталог, который должен приходить из поиска, на Flutter Web строить не стоит: ему нужен обычный сайт.
💸 Что теряет компания, если вспомнить об этом после релиза
Торговый представитель открывает портал у клиента, а первый экран висит: файлы грузятся с чужого сервера по плохой связи. Заказ придётся диктовать по телефону или записывать в Excel, и вечером кому-то придётся вносить его в 1С руками. Кладовщику на старом терминале сбора данных портал может не открыться, пока не обновят WebView, и машина стоит у ворот.
Дальше счёт идёт в часах разработки. Замена пакета с dart:html после релиза превращается в отдельную задачу: правка, приёмка и повторный прогон на каждом устройстве из списка. На старте проекта та же замена укладывается в обычную работу. Точную разницу в часах называть бессмысленно, она зависит от числа плагинов. Направление одно: после релиза дороже.
✅ Порядок проверки перед релизом
Шесть шагов, которые снимают большую часть сюрпризов:
- ✓Соберите список браузеров и устройств заказчика: запросите версии у администратора или возьмите User-Agent из логов веб-сервера. Отдельно отметьте Windows 7, терминалы сбора данных и iPhone.
- ✓Выполните flutter build web --wasm на текущем коде и выпишите пакеты, на которых сборка останавливается.
- ✓Решите, где живёт приложение: на отдельном поддомене с заголовками изоляции или без них, в одном потоке.
- ✓Положите CanvasKit и шрифты на свой сервер.
- ✓Прогоните вход, список заказов, загрузку файла, скачивание документа и обмен с 1С на реальных устройствах из первого шага.
- ✓Проверьте обе ветки: свежий Chrome даёт WASM, браузер без WasmGC даёт запасную JavaScript-сборку, и работать должны обе.
🛠️ Как мы подходим к этому в проектах и сколько это стоит
Проверку браузеров мы закладываем в проект с первой недели. Сначала просим у заказчика список браузеров и устройств, затем решаем, нужна ли WASM-ветка. Иногда честнее оставить JavaScript-сборку и не трогать заголовки сервера. Если вы выбираете подрядчика, спросите, на каких версиях Safari и Chrome он гонял сборку, и попросите показать список несовместимых пакетов.
Когда веб-клиент работает с учётной системой, вторая половина задачи лежит на стороне обмена данными. Как это устроено, описано на страницах про интеграцию приложения с 1С и B2B-приложение с 1С для заказов и отгрузок.
Если все устройства под вашим контролем, как терминалы склада и телефоны торговых, посмотрите на нативное приложение на 1С:Мобильной платформе. Оно не зависит от браузера, и вопрос кроссбраузерности снимается целиком. Платой станет установка приложения на каждое устройство и привязка к технологиям 1С.
По цене: разработка мобильных приложений у нас начинается от 500 000 ₽. Итог зависит от числа экранов, интеграций с 1С и состава устройств. Матрицу браузеров мы составляем и считаем до начала разработки, а не после релиза.
❓ Частые вопросы
Работает ли Flutter Web с WASM в Safari и на iPhone?
Результат зависит от версии iOS и версии Flutter. Все браузеры на iPhone работают на движке WebKit, поэтому ведут себя одинаково. Если WasmGC недоступен, загрузчик отдаёт запасную JavaScript-сборку. Если WASM-ветка ведёт себя нестабильно, её отключают, собрав проект без --wasm. Проверяйте на реальном iPhone, а не по таблицам совместимости.
Что будет, если у сотрудников Windows 7 и Chrome 109?
Приложение откроется: Flutter отдаст запасную JavaScript-сборку с CanvasKit, WasmGC ей не нужен. Chrome 109 стал последней версией для Windows 7. На слабом компьютере запасная сборка стартует дольше WASM-версии, поэтому замерьте первую загрузку на реальном рабочем месте. Если задержка мешает работе, упростите тяжёлые экраны или рассмотрите нативное приложение.
Нужны ли заголовки COOP и COEP для Flutter Web с WASM?
Заголовки COOP и COEP нужны только для многопоточной отрисовки skwasm. Без них приложение запустится в одном потоке. Эти заголовки блокируют сторонние ресурсы без разрешающих заголовков, поэтому ставьте их на отдельном поддомене приложения и заранее проверьте платёжные формы, карты в iframe и счётчики. Для небольшого закрытого кабинета многопоточность часто не нужна.
Почему сборка Flutter Web с флагом --wasm падает с ошибкой?
Чаще всего сборку ломает пакет, который импортирует dart:html, dart:js, dart:js_util или package:js: компилятор dart2wasm их не поддерживает. Ошибка показывает, в каком пакете проблема. Дальше три варианта: обновить пакет до версии на package:web и dart:js_interop, заменить его аналогом или обернуть нужный вызов собственным кодом.
Сколько стоит разработка приложения с веб-версией и обменом с 1С?
Разработка мобильных приложений у нас начинается от 500 000 ₽. Итоговая цена зависит от числа экранов, интеграций с 1С и списка устройств. Проверку браузеров, включая WASM-ветку и запасную сборку, мы считаем вместе со сметой. Для точной оценки нужны список функций и перечень браузеров и устройств заказчика.
Или позвоните: +7 906 045-28-27 — в рабочее время с 9:00 до 19:00
Остались вопросы? Нужна помощь?
Менеджеры компании с радостью ответят на ваши вопросы, произведут расчет стоимости услуг и подготовят индивидуальное коммерческое предложение.
Бесплатная консультация

