Flutter Webの可能性を探ってみる(主にマップ周り)
やりたいこと
今度作る(かもしれない)アプリで、Flutter webを使うかもしれないので、どのくらい現実的に使えるものなのか調べてみる
- そもそも動くのか
- できないことは?
- パフォーマンスは良好なのか?
Flutter on the Web
が正式名称とのこと
モバイルとはちょっと仕組み違う。モバイルは独自のレンダリングエンジンを使って動かしているはず(うろ覚え)
canvaskit側に以下のように書いてあるけど、これはDart→ロジック部分、UI→Widgetとして書いた部分(Flutterに近いところ)みたいな理解でいいのかな?
Dart code is compiled to JavaScript, and the UI is rendered on the main thread into WebGL.
Google EarthはFlutter on the Web で動いている模様。
Flutter3.22からWasmサポートがstableになった。それまではJavaScriptサポートのみ。
Wasmってなんだ?
W3Cが2019年に標準化した、Webブラウザ上で動作する第4の言語。
対応している任意のプログラミング言語を中間言語へと変換し、Wasmファイル(.wasm)として保存する。実行時にブラウザによってWebアプリケーションの一部としてダウンロードされ、ブラウザによって検証された後にプロセッサに応じた機械語へと変換されて動作する。
以下の特徴を持つ
Language-independent (言語非依存)
Portable/Platform-independent (ポータブル/プラットフォーム非依存)
Safe (安全)
Fast (高速)
FlutterでWasmビルドされたアプリを使用するには、ブラウザがWasmGC(WebAssembly Garbage Collection)なるものをサポートしている必要がある。
To run a Flutter app that has been compiled to Wasm, you need a browser that supports WasmGC.
flutter build web
でWebアプリをビルドしてみた。
$ tree build/web
build/web
├── assets
│ └── 省略
├── canvaskit
│ ├── canvaskit.js
│ ├── canvaskit.js.symbols
│ ├── canvaskit.wasm
│ ├── chromium
│ │ ├── canvaskit.js
│ │ ├── canvaskit.js.symbols
│ │ └── canvaskit.wasm
│ ├── skwasm.js
│ ├── skwasm.js.symbols
│ ├── skwasm.wasm
│ └── skwasm.worker.js
├── favicon.png
├── flutter.js
├── flutter_bootstrap.js
├── flutter_service_worker.js
├── icons
│ └── 省略
├── index.html
├── main.dart.js
├── manifest.json
└── version.json
flutter build web --wasm
でビルドした結果、main.dart.mjs
とmain.dart.wasm
というファイルが追加でビルドされていた。
ビルドしたものをローカルで動かしてみる
dhttpd '--headers=Cross-Origin-Embedder-Policy=credentialless;Cross-Origin-Opener-Policy=same-origin'
このオプションの通りで、サーバーからこのヘッダーが帰らないと多分Wasmで動かないんだと思う。
オプションあり
オプションなし
私はマップ表示を頻繁に使用するため、マップ表示を試してみる(
https://pub.dev/packages/google_maps_flutter_web を見れば一通りセットアップは簡単にできた。
パッケージはgoogle_maps_flutterとgoogle_maps_cluster_managerを使用した。
色々触ってて気づいたけど、そもそも現在位置が表示されてない。
既知の問題で、myLocationButtonEnabled
とmyLocationEnabled
のオプションは無視されるとのこと。
もっと基礎的なところで、そもそもWeb対応しているパッケージ名はpub.devでPlatforms:Webで調べれば出てくる
(個人的に)よく使うパッケージ名について調べてみた
パッケージ名 | Web対応しているか | メモ |
---|---|---|
http | ⭕️ | Clientを使い分ける必要あり? |
shared_preferences | ⭕️ | LocalStorageで実現 |
geolocator | ⭕️ |
getLastKnownPosition やアプリ設定画面を開くメソッドは非対応 |
flutter_secure_storage | ⭕️ | WebCryptoを使用して実現。セキュリティ対策必須。 |
riverpod | ⭕️ | |
flutter_inappwebview | ⭕️ | |
google_maps_cluster_manager | ⭕️? | 特に使えるとは書いてなかったが、結果使えた |
デプロイしようと思い難読化周りが気になった。
Web apps don't support obfuscation. A web app can be minified, which provides a similar result. When you build a release version of a Flutter web app, the web compiler minifies the app. To learn more, see Build and release a web app.
ビルドする時に軽量化を行なっており、それによって難読化と同様の結果が得られるらしい
デプロイしてみる。
柿を参考に単一のFirebaseプロジェクトで、3つのビルド方法でデプロイしてみた
flutter build web --wasm
flutter build web --web-renderer canvaskit
flutter build web --web-renderer html
https://pagespeed.web.dev/?hl=ja で速度を計測してみたが、大きな違いはなさそうだった
wasmビルド
canvaskitビルド
htmlビルド
Flutter Webの2024年のロードマップをみると
We'll continue to focus on performance and quality, including investigating reducing the overall application size, better use of multi-threading, supporting platform views, improving app load times, making CanvasKit the default renderer, improving text input, and investigating options for supporting SEO for Flutter web.
We expect to complete the effort to compile Dart to WasmGC, and with that support Wasm compilation of Flutter web apps. This also includes a new JS interop mechanism for Dart that supports both JS and Wasm compilation.
We also plan to resume work to support hot reload on the web.
- SEO→未対応
- WASMビルド→対応完了、あとはブラウザ対応待ち
- ホットリロード→未対応