Flutter WebAssembly (Wasm) 支持 - 实用指南
概述
WebAssembly (Wasm) 是一种低级的二进制格式,旨在成为高级语言(如 Dart)在 Web 平台上的编译目标。它能提供接近原生的执行性能。
Flutter 和 Dart 在构建 Web 应用时,支持将应用编译为 WebAssembly 格式。这标志着 Flutter Web 应用在性能上的一次重大飞跃。
核心优势:
- 性能提升: Wasm 代码执行效率远高于 JavaScript,尤其适用于计算密集型操作。
- 启动优化: 可以带来更快的应用启动速度。
- 多线程渲染: 利用高级浏览器特性,实现多线程渲染,减少卡顿 (Jank)。
开始使用
1. 切换到最新版本的 Flutter
要编译和运行 Wasm 应用,你需要 Flutter 3.24 或更高版本。
bash
flutter upgrade
2. 确保你的应用依赖项兼容
- 尝试使用默认的模板示例应用 (
flutter create my_wasm_app
)。 - 或者,确保你现有的 Flutter 应用已迁移至支持 Wasm 的依赖项。一些旧的、依赖于
dart:html
或package:js
的包可能需要更新。
3. 更新 Index 页面
确保你应用的 web/index.html
文件已更新为 Flutter 3.22+ 的最新初始化方式。
简单方法 : 删除 web/
目录下的所有内容,然后重新生成:
bash
flutter create . --platforms=web
4. 运行或构建你的应用
-
开发运行 (使用 Chrome 浏览器):
bashflutter run -d chrome --wasm
-
生产构建:
bashflutter build web --wasm
输出文件位于
build/web/
目录,与标准 JavaScript 构建输出位置相同。
5. 在兼容的浏览器中打开应用
即使使用了 --wasm
标志,Flutter 也会同时生成 JavaScript 和 Wasm 代码。运行时如果浏览器不支持 WasmGC,则会自动回退到 JavaScript 版本,保证应用在所有主流浏览器中都能工作。
如何检测应用是否正在以 Wasm 模式运行?
-
推荐方法: 检查编译时设置的环境变量。
dartconst bool isRunningWithWasm = bool.fromEnvironment('dart.tool.dart2wasm'); if (isRunningWithWasm) { print('Running on WebAssembly! 🚀'); } else { print('Running on JavaScript (fallback mode).'); }
-
备用方法: 利用数字表示的差异进行检测。
dartfinal bool isRunningWithWasm = identical(double.nan, double.nan);
重要配置:部署与 HTTP 头
为了启用 多线程渲染 以获得最佳性能,你的 HTTP 服务器必须配置特定的响应头。
头部名称 (Name) | 值 (Value) |
---|---|
Cross-Origin-Embedder-Policy |
credentialless 或 require-corp |
Cross-Origin-Opener-Policy |
same-origin |
如果不设置这些头部,应用将无法使用多线程渲染功能。
浏览器兼容性
要运行编译为 Wasm 的 Flutter 应用,你需要一个支持 WasmGC (垃圾回收) 的浏览器。
浏览器 | 支持情况 | 说明 |
---|---|---|
Chrome | ✅ 119+ (桌面版 & Android) | 基于 V8 引擎,支持良好。 |
Edge | ✅ 119+ | 基于 Chromium,支持同 Chrome。 |
Firefox | ⚠️ 120+ 宣布支持,但目前因 Bug 不可用 | 存在一个 已知 Bug 阻止与 Flutter Wasm 渲染器兼容。需要关注此问题进展。 |
Safari | ⚠️ 技术预览版支持,但目前因 Bug 不可用 | 存在一个 类似 Bug 阻止兼容。需要关注此问题进展。 |
iOS 所有浏览器 | ❌ 不支持 | 所有 iOS 浏览器都必须使用 WebKit 内核,而 WebKit 对 WasmGC 的支持尚未就绪,无法运行 Flutter Wasm 应用。 |
警告 : 编译为 Wasm 的 Flutter 应用无法在任何 iOS 设备上的浏览器中运行。
使用兼容的 JS 互操作库
为了支持编译到 Wasm,Dart 改变了与浏览器和 JavaScript API 交互的方式。
不再支持以下旧方式:
dart:html
package:js
dart:js
请使用新的、轻量级的静态 JS 互操作方案:
package:web
: 替代dart:html
,提供了对 Web API 的现代互操作支持。dart:js_interop
: 替代package:js
和dart:js
,提供了更安全、更高效的底层 JS 互操作能力。
深入学习 : 查阅官方 Dart JS 互操作文档。
总结与行动清单
- 升级 Flutter :
flutter upgrade
(确保 >= 3.24) - 检查依赖: 使用新项目测试或迁移旧项目依赖。
- 更新 Web 目录 :
flutter create . --platforms=web
- 运行/构建 : 记得加上
--wasm
标志。 - 测试: 在 Chrome (119+) 中测试 Wasm 模式,并在其他浏览器中测试回退模式。
- 部署准备 : 务必 为你的服务器配置
COEP
和COOP
HTTP 头以启用多线程。 - 代码迁移 : 如果使用了旧的 JS 互操作,计划迁移到
package:web
和dart:js_interop
。 - 告知用户: 明确你的应用在 iOS 浏览器上无法以 Wasm 模式运行(会回退到 JS)。
通过遵循本指南,你可以成功地将你的 Flutter Web 应用带入 WebAssembly 的高性能世界。