😽

Flutterを用いたWeb開発の今後について考える

2023/08/03に公開
2

この記事は『blessing software 夏のブログリレー企画』の4日目の記事です。
昨日はGANGANさん@gangan_nikkiESLintモジュールを用いてNuxt3 + ESLint設定を行うが公開されました。

明日は鉄馬さん@tekihei2317_個人開発アプリをRemix + Cloudflare D1に移行してみたが公開される予定です!お楽しみに!

Flutterを用いたWebアプリ開発の課題

2021年にFlutter2が出た際に、WebのサポートがStableになりました。その際に簡単なWeb Appを作ったのですが、大きく3つの課題があると感じていました。

  1. Webページにしてはファイルサイズが大きい
  2. Canvasを用いてレンダリングするため、Webページとして扱いづらい
  3. フォントをWebフォントを利用して描画するため、フォントのダウンロードを行っている間にTofuになる

Webページにしてはファイルサイズが大きい

アプリだからと割り切ってしまう場合は良いですが、Webページとして考えるのであればファイルサイズの肥大化は看過できない問題となります。

Webの優れたUXと言われて読者が思い浮かべるのは阿部寛さんの非公式ホームページでしょう。

Webページを表示する際、ブラウザとサーバの間には常にネットワークがあります。Webページを開くには、ブラウザがサーバーと通信して表示するコンテンツ内容をダウンロードしてくる必要があります。この時、利用しているネットワークの帯域が狭いとダウンロードするのに時間がかかりなかなか最初のページが表示されないと言った事態に陥ります。これは利用ユーザーとしてはストレスを感じる場面の1つです。

Canvasを用いてレンダリングするため、Webページとして扱いづらい

Flutterは独自のレンダリングエンジンを用いて画面を表示します。これはWebにおいても同様で、Flutterを用いてWebアプリを開発する場合、そのWebアプリはCanvasを用いてレンダリングが行われます。
HTMLタグを用いたレンダリング自体も用意はされていますが、現時点でこちらは描画スピードCanvas版に比べて遅かったり、表示崩れを起こすと言った問題があり、デメリットの方が大きいと感じます。

--web-renderer canvaskitを指定することでCanvasによるレンダリングを常に実現することができます。
https://github.com/a-skua/example-flutter-web/blob/90518dd14b049ce2b190e9a76cbc9c03eba403cd/app/Makefile#L7

しかし、Canvasを用いたレンダリングは文字も含めて1枚の画像として扱われるため、通常のWebページのようにテキストを選択してコピーすることができません。これはWebページを作りたい場合にFlutterは最適解ではないと感じてしまう場面です。

8/14追記

コメントにて、Flutter3.3にてSelectionAreaが追加されているという情報をいただきました。
Web上でもテキストを選択しやすくなっています。

SelectableAreaの例

https://medium.com/flutter/whats-new-in-flutter-3-3-893c7b9af1ff

フォントをWebフォントを利用して描画するため、フォントのダウンロードを行っている間にTofuになる

Canvasを用いたレンダリングの場合、表示するフォントはWebフォントを用います。そのため、フォントのデータをダウンロードできるまで、テキストがTofuになる問題があります。
これはレンダリングにCanvasを用いる場合の明確なデメリットではありますが、表示崩れが起きないことやパフォーマンスを考えるとCanvas版を選ぶべきだと思います。

Tofuになるテキストフィールド

Webサポートの動向

直近のFlutterのWebサポートで特筆すべきものが2つありました。

  1. WebAssmblyのサポート
  2. Web Embedded

WebAssmblyのサポート

Flutterの開発言語に用いられているDartが現在WebAssemblyへのコンパイルを試験的に進めています。
これはまだDartのビルドオプションに含まれてはいませんが、FlutterではWebビルドする際にWasmへビルドすることができるようになっています。実行するにはブラウザのサポートがまだ試験段階ということもあり本格的に利用できるようになるのはまだ先のことですが、パフォーマンスがさらに改善されることやより実行ファイルを小さくすることができるといったことが期待されています。

https://youtu.be/Nkjc9r0WDNo

--wasmを指定することで、Wasm版を試すことができます。
https://github.com/a-skua/example-flutter-web/blob/90518dd14b049ce2b190e9a76cbc9c03eba403cd/app/Makefile#L4

Web Embedded

FlutterをWebページ内に埋め込むことができるようになりました。
今までもFlutterで作られたページをiframeを用いて埋め込むということは可能でしたが、Webページ内のElementの1つとして埋め込むことができるようになり、相互にに呼び出すことが可能になりました。

FlutterとJSの相互通信

特に、Web版では日本語の入力に関してフォントのTofu問題やIMEの変換問題がありましたが、入力周りをWebの既存資源(HTML, JS, CSS)を用いて補間することができればUXの向上を期待できます。

実装例

JSからアクセスしたいオブジェクトやメソッドに対して@JSExport()アノテーションをつけ、setPropertyを用いることで、JSからFlutterのオブジェクトやメソッドにアクセス可能になります。

https://github.com/a-skua/example-flutter-web/blob/90518dd14b049ce2b190e9a76cbc9c03eba403cd/app/lib/main.dart#L24-L27

https://github.com/a-skua/example-flutter-web/blob/90518dd14b049ce2b190e9a76cbc9c03eba403cd/app/lib/main.dart#L37-L38

https://github.com/a-skua/example-flutter-web/blob/90518dd14b049ce2b190e9a76cbc9c03eba403cd/app/web/index.html#L63

どうも現時点ですとFlutterのWeb版はESModule対応していないようで、多少扱いに困る部分がありそうですが、DartからWasmへビルドした際に生成されるJSはESModule版のようですので、今後ESModuleとして扱えるようになるとより利用できる幅が広がることが期待できます。

まとめ

Flutterを用いたWeb開発が主流になるかと聞かれると主流になると言い切れませんが、そろそろ実用できそうだなと雰囲気を個人的には感じています。
とはいえ、アプリをWebに移植したり、CI/CDの一環で動作確認をブラウザ上で行うといった点ではすでに十分に利用できる状況だとは思います。
Wasm版のFlutterが正式に世に出れば、アプリのWeb移植はより行いやすくなるでしょう。DartにおけるWasmのサポートは今後注目のトピックの1つです。

記事のデモに利用したWebページはこちらから確認できます。

HTMLにMaterial3を適用した例

最後に

縁あってFlutterKaigi2023の運営に関わっているため、宣伝させていただきます。

FlutterKaigi2023

今年のFlutterKaigi2023は11/10(金)にオフライン開催を予定しており、現在(〜8/20まで)セッションの募集を行っています。
セッションの応募はFlutterKaigi 2023 セッション募集についてに記載されている募集要項から行うことができます。
カンファレンスは界隈の人と交流できる機会でもあります。Flutter(やDart)の技術トピックについて語りたいという方、ぜひ応募しましょう。話を聞いてみたいという方も、当日会えることを楽しみにしています。

Kobe.ts

Discussion

koji-1009koji-1009

Flutter Webで文字列が選択できない問題ですが、SelectionArea(もしくはSelectableText)が利用できる点にも触れてあると良さそうな気がしました。

https://api.flutter.dev/flutter/material/SelectableText-class.html
https://master-api.flutter.dev/flutter/material/SelectionArea-class.html

DesktopやWebにおける体験の向上を目指してFlutter 3.3からSelectionAreaが追加されています。CanvasKitを利用する場合でも、SelectionAreaを設定することで、HTML版と同等の振る舞いを実現できるように思います。
https://medium.com/flutter/whats-new-in-flutter-3-3-893c7b9af1ff

asukaasuka

DesktopやWebにおける体験の向上を目指してFlutter 3.3からSelectionAreaが追加されています。

こちら、私の方で気がつけていませんでした。
追記する形で記事の修正します! 言及ありがとうございます!!