支援 WebAssembly (Wasm)
Flutter 與 Dart 支援將 WebAssembly 作為網頁應用程式的編譯目標。
開始使用
#若想體驗預先建置的 Flutter WebAssembly 應用程式,請參考 Wonderous demo app。
若要在自己的應用程式中嘗試 Wasm,請依照以下步驟操作。
切換到最新版本的 Flutter
#請切換至 Flutter 3.24 或更高版本, 以便執行並編譯 Flutter 應用程式至 WebAssembly。 為確保您使用的是最新版本,請執行 flutter upgrade。
確認應用程式的相依套件相容
#您可以嘗試預設範本 sample app, 或選擇任何已遷移為 相容 Wasm 的 Flutter 應用程式。
修改 index 頁面
#請確保您的 web/index.html 已更新為 Flutter 3.22 及之後版本的 Flutter web app initialization。
如果您想使用預設設定,請刪除 web/ 目錄中的所有內容,然後執行下列指令以重新產生:
flutter create . --platforms web執行或建置您的應用程式
#若要在開發或測試時以 Wasm 執行應用程式,請在flutter run指令中加入--wasm旗標。
flutter run -d chrome --wasm要建立一個使用 Wasm 的網頁應用程式,請在現有的 flutter build web 指令中加入 --wasm 旗標。
flutter build web --wasm該指令會將輸出產生在相對於套件根目錄的 build/web 目錄中,就像 flutter build web 一樣。
在相容的網頁瀏覽器中開啟應用程式
#即使加上 --wasm 旗標,Flutter 仍然會將應用程式編譯為 JavaScript。如果在執行時未偵測到 WasmGC 支援,則會使用 JavaScript 輸出,因此應用程式仍可在所有主流瀏覽器中正常運作。
你可以透過檢查在編譯期間設定的 dart2wasm 環境變數(建議方式),來驗證應用程式是否實際以 Wasm 執行。
const isRunningWithWasm = bool.fromEnvironment('dart.tool.dart2wasm');或者,您也可以利用數值表示方式的差異,來測試是否使用了原生(Wasm)數值表示方式。
final isRunningWithWasm = identical(double.nan, double.nan);使用 HTTP 伺服器提供建置後的輸出
#Flutter Web WebAssembly 可以利用多執行緒來更快地渲染你的應用程式,減少卡頓現象。為了達成這一點,Flutter 會使用進階的瀏覽器功能,而這些功能需要特定的 HTTP 回應標頭(HTTP response headers)。
| 名稱 | 值 |
|---|---|
Cross-Origin-Embedder-Policy | credentialless 或 require-corp |
Cross-Origin-Opener-Policy | same-origin |
想進一步了解這些標頭,請參考 Load cross-origin resources without CORP headers using COEP: credentialless。
進一步了解瀏覽器相容性
#要執行已編譯為 Wasm 的 Flutter 應用程式,你需要一個支援 WasmGC 的瀏覽器。
Chromium 和 V8 自第 119 版起支援 WasmGC。 iOS 上的 Chrome 使用 WebKit,目前尚未 支援 WasmGC。 Firefox 在 Firefox 120 宣布穩定支援 WasmGC, 但目前因已知限制而無法運作(詳情見下方)。
- 為什麼不能用 Firefox? Firefox 120 版及之後的版本過去可以執行 Flutter/Wasm,但目前遇到一個錯誤,導致與 Flutter 的 Wasm renderer 不相容。詳情請追蹤 此錯誤。
- 為什麼不能用 Safari? Safari 現已支援 WasmGC,但也遇到類似的錯誤,導致與 Flutter 的 Wasm renderer 不相容。 詳情請追蹤 此錯誤。
使用相容的 JS interop 函式庫
#為了支援編譯至 Wasm,Dart 已改變其與瀏覽器及 JavaScript API 互通的方式。 這導致使用 dart:html 或 package:js 的 Dart 程式碼 無法編譯為 Wasm。
取而代之的是,Dart 現在提供了全新、輕量級,且以靜態 JS interop 為核心的解決方案:
package:web,可取代dart:html(以及其他 web 函式庫)dart:js_interop,可取代package:js與dart:js
想進一步了解 Dart 的 JS interop, 請參考 Dart 的 JS interop 文件頁面。