跳转至正文

对 WebAssembly(Wasm)的支持

Flutter 对 WebAssembly(Wasm)支持的当前状态。

Flutter 与 Dart 支持将 WebAssembly 作为为 Web 构建应用时的编译目标。

入门

#

要试用使用 Wasm 构建的 Flutter Web 应用,可查看 Wonderous 演示应用

若要在自己的应用中试验 Wasm,请按以下步骤操作。

切换到最新版 Flutter

#

请切换到 Flutter 3.24 或更高版本,以运行并将 Flutter 应用编译为 WebAssembly。要确保使用最新版本,请运行 flutter upgrade

确保应用依赖兼容

#

请尝试默认模板示例应用,或选择已迁移为与 Wasm 兼容的任意 Flutter 应用。

修改索引页

#

请确保应用的 web/index.html 已更新为适用于 Flutter 3.22 及更高版本的最新 Flutter Web 应用初始化

若要使用默认配置,请删除 web/ 目录内容并运行以下命令重新生成:

flutter create . --platforms web

运行或构建应用

#

要在开发或测试时使用 Wasm 运行应用,请在 flutter run 命令中使用 --wasm 标志。

flutter run -d chrome --wasm

要使用 Wasm 构建 Web 应用,请在现有的 flutter build web 命令中添加 --wasm 标志。

flutter build web --wasm

该命令会在相对于包根的 build/web 目录中生成输出,与 flutter build web 相同。

在兼容的 Web 浏览器中打开应用

#

即使使用 --wasm 标志,Flutter 仍会将应用编译为 JavaScript。若运行时未检测到 WasmGC 支持,将使用 JavaScript 输出,因此应用仍可在所有主流浏览器中运行。

你可以通过检查编译时设置的 dart2wasm 环境变量来验证应用是否实际以 Wasm 运行(推荐)。

dart
const isRunningWithWasm = bool.fromEnvironment('dart.tool.dart2wasm');

或者,你可以利用数字表示方式的差异来测试是否使用了原生(Wasm)数字表示。

dart
final isRunningWithWasm = identical(double.nan, double.nan);

使用 HTTP 服务器提供构建输出

#

Flutter Web WebAssembly 可使用多线程更快渲染应用并减少卡顿。为此,Flutter 使用需要特定 HTTP 响应标头的高级浏览器功能。

NameValue
Cross-Origin-Embedder-Policy credentialless
or
require-corp
Cross-Origin-Opener-Policysame-origin
名称
Cross-Origin-Embedder-Policy credentialless

require-corp
Cross-Origin-Opener-Policysame-origin

要了解这些标头的更多信息,请参阅使用 COEP: credentialless 加载无需 CORP 标头的跨域资源

了解更多浏览器兼容性信息

#

要运行已编译为 Wasm 的 Flutter 应用,你需要支持 WasmGC 的浏览器。

Chromium 与 V8 自 119 版起支持 WasmGC。iOS 上的 Chrome 使用 WebKit,目前尚不支持 WasmGC。Firefox 在 120 版宣布稳定支持 WasmGC,但由于已知限制目前无法工作(详见下文)。

  • 为何不用 Firefox? Firefox 120 及更高版本此前可以运行 Flutter/Wasm,但目前存在一个阻碍与 Flutter Wasm 渲染器兼容的 bug。详情请关注此 bug

  • 为何不用 Safari? Safari 现已支持 WasmGC,但存在类似 bug,阻碍与 Flutter Wasm 渲染器的兼容。详情请关注此 bug

使用兼容的 JS 互操作库

#

为支持编译到 Wasm,Dart 改变了与浏览器和 JavaScript API 互操作的方式。这会导致使用 dart:htmlpackage:js 的 Dart 代码无法编译为 Wasm。

取而代之的是,Dart 现在提供基于静态 JS 互操作的新轻量方案:

要了解 Dart 中的 JS 互操作,请参阅 Dart 的 JS interop 文档页面。