ちょっとだけ詳しいFlutter Web 描画の仕組み 2024年版
はじめに
株式会社メンバーズ、Cross Applicationカンパニーの柴田です。
いきなりですが質問です。FlutterでWebアプリを作成した際、Dartで書いたコードがどのように描画されるか意識したことはありますか?特にリソースが制限されているWebアプリでは、描画方法がユーザー体験に大きな影響を与えるため、その理解が非常に重要です。また、Flutter Webの将来性について判断する際にもどのような技術的アプローチを行っているかを知ることは大切です。
Flutter Webの描画方法(レンダラー)には、HTML、CanvasKit、Skwasm(Wasm)の3つの選択肢があります。この記事では、それぞれのレンダラーの特徴や利点、課題についてちょっとだけ詳しく解説していきます。最適な選択をするための参考にしてみてください。
レンダラーの種類
HTML
HTMLレンダラーは、HTML、JavaScriptを使用して描画を行う方式です。このアプローチの利点は、他の方式と比べてファイルサイズが小さく初期表示を早くできる点です。
欠点は複雑なUI時はパフォーマンスが落ちることです。
PRやIssueを見るとHTMLレンダラーが今後非推奨になるようです。そのため、HTMLレンダラーに触れる機会は減っていくと思われます。
HTMLレンダラーを使用するビルドコマンドは以下の2通りです。
web-rendererをautoにした場合はモバイルウェブの時HTMLレンダリングが、モバイルウェブ以外の場合CanvasKitレンダリングが使用されます。
flutter build web –web-renderer html
flutter build web –web-renderer auto
CanvasKit
CanvasKitレンダラーは、JavaScriptにコンパイルしたDartと、Skia*のWebAssembly(Wasm)版であるCanvasKitモジュールを用いる方式です。WebGL、ハードウェアエンコーダ等を用いているため、HTMLレンダラーに比べて複雑なUIをパフォーマンス良く描画することができます。
この方式の欠点はCanvasKitモジュールのファイルサイズが約1.5 MBと大きいことです。ただ、ファイルサイズは年々小さくなってきているので、古いFlutterバージョンを使用されている方はバージョンアップすると初期速度が短縮することができます。
*SkiaとはChrome、Firefox、Android等でも採用されているC++で書かれた2Dグラフィックライブラリです。iOS以外のFlutterアプリではデフォルトレンダラーがSkiaになっています。余談ですがiOSはパフォーマンスの問題で、Flutter 3.10以降独自開発したImpellerがデフォルトレンダラーになっています。AndroidやmacOSも今後Impellerをデフォルトレンダラーにしていく計画のようです。
Canvaskitレンダラーを使用するビルドコマンドは以下の4通りです。
最初の3つは同じ動作になります。
web-rendererをautoにした場合はモバイルウェブの時HTMLレンダリングが、モバイルウェブ以外の場合CanvasKitレンダリングが使用されます。
flutter build web
flutter build web –no-wasm
flutter build web –web-renderer canvaskit
flutter build web –web-renderer auto
Skwasm(Wasm)
Skwasm(Wasm)レンダラーは、CanvasKitレンダラーと似ていてCanvasKitモジュールを用いていますが、DartがJavaScriptではなくWasmにコンパイルされ描画処理はWasmで行います。そのため、CanvasKitレンダラーに比べてパフォーマンスが良いのが特徴です。また、CanvasKitモジュールのファイルサイズが約1.1MBとCanvasKitレンダラーより少し小さくなっています。Flutterの3.22以降、この方式は安定版として利用可能になりました。
ただし、Skwasmにも欠点があります。この方式を利用するにはブラウザにWasmGCという機能が実装されている必要があり、対応ブラウザが限られます。現時点(2024/10/09)では、Chrome 119以降(iOS版を除く)が対応しています。FirefoxもFirefox 120で実装済みですが、バグがありFlutterアプリが正常に動作しないようです。Safariに関しては、現在開発者プレビュー中です。
一部の環境でしか正常に動作しないように見えるSkwasmですが、救済処置もあります。実はビルド時にWasmだけでなくJavaScript にコンパイルしたファイルも出力されており、実行時にブラウザをチェックしてWasm版で動かすかJavaScript版で動かすかを自動で判別するフォールバック機構が搭載されてます。コードを見ると現時点ではBlinkを使っているChromeとEdgeのみでWasm版を使用するようです。
Skwasmを使用するビルドコマンドは以下の2通りです。
どちらも同じ動作になります。
flutter build web –wasm
flutter build web –web-renderer skwasm
レンダラーの選び方
選び方のおすすめは一番パフォーマンスが良いSkwasmで動作確認を行い問題がなければSkwasmを採用し、問題があればCanvasKit、次にHTMLという順に選択する方法です。実行するOSやブラウザによってレンダラーを変更したい場合は、 web/index.html を修正することで細かく制御することができます。以前私が参加していた案件では、一部のAndroid端末 + CanvasKitで表示が崩れるFlutterのバグ(Issueを見る限り現在は解消済)があり、User Agentを元にAndroidの場合はHTMLレンダラーで、Android以外の場合はCanvasKitレンダラーで起動するJavaScriptのコードを追記していました。
まとめ
Flutter Webの3種類のレンダラー、HTML、CanvasKit、Skwasmの特徴と、選び方について見てきました。現在はまだChromeやEdgeでしかSkwasmを使えませんが、今後主要ブラウザでWasmGCが動作するようになり、Skwasm(Wasm)が多くのブラウザで動くようになるとFlutter Webがまた新たなフェーズへと進化していきそうで楽しみですね!
参考サイト:
Support for WebAssembly (Wasm)
Web renderers
Github flutter/flutter
Github flutter/engine
この記事を書いた人
関連記事
- React Redux: 毎回新しい参照を返す select...
Daisuke Yamamura
- 画像のカラー抽出を頑張った話。
狩野真毅
- 3Dの第一歩、Blenderを活用してひとつ先の未来へ
スーパーたけちゃんマン