2021.03.23
Flutter 2で使えるWebAssemblyレンダラー CanvasKit は本当に高速なのか?
こんにちは。F.S. です。
2021年3月3日に開催されたFlutter EngageでFlutter 2が正式リリースされ、WebアプリサポートがStableとなりました。また、Webアプリのレンダラーに従来のHTMLレンダラーに加えてパフォーマンスが高いとされるCanvasKitを正式に利用できるようになりました。
今回はFlutter 2 Webアプリのレンダラーの違いによるパフォーマンスを比較検証します。
1.CanvasKitとは
Flutter製のネイティブアプリは2DグラフィックライブラリSkiaを用いて画面をレンダリングします。これは各OSのネイティブコンポーネントを使用するReact Native製アプリとは違う大きな特徴で、OSに依存せず統一されたインターフェースを提供することになります。
CanvasKitはSkiaをWebAssemblyにビルドして、Webアプリで使えるようにしたものです。
2.Flutter 2におけるWebレンダラーの選択
Flutter 2のWebアプリでは、デフォルトではレンダラーが自動で選択されます。
CanvasKitを利用する場合はレンダラーのバイナリ(canvaskit.wasm)がダウンロードされることによって転送データが約2MB増えるため、通信環境を考慮してモバイルブラウザではHTMLレンダラー、デスクトップブラウザではCanvasKitが選択されるとのことです。
詳細は以下のリソースを参考ください。
- Web renderers – Flutter(公式ドキュメント)
- From mobile app to web app – YouTube(Flutter Engageセッション動画)
※canvaskit.wasmのサイズは、3/16時点、手元で確認したところでは転送サイズで2.5MB、リソースサイズは6.7MBとなっていました。
なお、レンダラーの選択はデフォルトでは自動選択ですが、run または build で --web-renderer オプションをつけることでレンダラーを指定することもできます。
例)
flutter run -d chrome --web-renderer html
flutter build web --web-renderer canvaskit
3.Webレンダラー性能検証
3-1.検証方法
HTML, CanvasKitそれぞれのレンダラーを指定してビルドしたFlutter Webアプリケーションにおいて、レンダリング負荷の高いパーティクルアニメーションを表示した時の画面のリフレッシュレート(FPS)を計測します。
Flutterの画面のリフレッシュレートは60FPSを保つようになっているのですが、パーティクルの数を増やしてレンダリングの負荷を高めていくとFPSがどのように変化していくか、レンダラーごとの違いを見ていきます。
パーティクルアニメーションにはFlutter公式のサンプルにあるこちら↓を使用します。
Particle Background – Flutter Samples
パーティクル数は1,000から始めて倍々に増やしていき、64,000までの7パターン計測します。パーティクルのサイズは、数多く生成するためにオリジナルより小さくしています。
これを同一条件において10秒間×3回計測し、FPS値の統計をとることにします。
3-2.検証ブラウザ
下表の通りデスクトップ、モバイル各種OSの、各種ブラウザ(レンダリングエンジン)にて検証を行います。
[table id=8 /]
(補足)
デスクトップブラウザにおいては、スクリーンサイズに統一性を持たせるために開発ツールで下記端末のスクリーンをエミュレートして検証します。
- iPhone 6/7/8 Plus相当(414×736、DPR 3)
4.検証結果
検証時点でのFlutterのバージョンは 2.0.2 です。
CanvasKitは 0.24.0 (https://unpkg.com/[email protected]/bin/canvaskit.wasm)が利用されていました。
それでは各ブラウザにおける結果を見ていきたいと思います。
1.MacBook Pro (13-inch, 2020) , macOS 10.15.7 , Chrome (89.0.4389.82) , Blink
パーティクル数4,000あたりから差が出始め、CanvasKitの方が30〜40%程度高いパフォーマンスを出しているように見えます。
2.MacBook Pro (13-inch, 2020) , macOS 10.15.7 , Safari (14.0.3) , WebKit
Safari(WebKit)においては両レンダラーの性能にあまり違いが見られません。なお、HTMLレンダラーにおいても前述のChromeより高いパフォーマンスが出ています。一方、Chromeと比較して外れ値が多く、安定性に欠けるようにも思えます。
ちなみに、WebKitブラウザでは時間がミリ秒精度までしか取れないようであり、1,000パーティクルでも中央値が60FPSを若干下回る計算結果となっているのはそのためです。
3.MacBook Pro (13-inch, 2020) , macOS 10.15.7 , Firefox (86.0.1) , Servo
2,000〜4,000におけるFPS値の幅に違いはあるものの、中央値においてはSafari同様に両レンダラーの性能差がほとんど見られません。
4.Dell OptiPlex 5050 , Windows 10 Pro (1903) , Chrome (89.0.4389.90) , Blink
検証機がグラフィックに強くないと思われ、最高でも30FPS強ですが、中央値を見るとmacOSのChrome同様にCanvasKitの方が性能が高いことがわかります。
5.Dell OptiPlex 5050 , Windows 10 Pro (1903) , Edge (89.0.774.54) , Blink
EdgeはChromeと同じChromium(Blinkエンジン)なので、Chromeとほぼ同等の結果となっています。
6.Dell OptiPlex 5050 , Windows 10 Pro (1903) , Firefox (82.0.3) , Servo
macOS Firefoxと同様に、両レンダラーで性能差がほとんど見られません。
7.iPhone XR , iOS 14.4 , Sarari , WebKit
macOS Safariと同様、両レンダラーで性能差がほとんど見られません。また、特にCanvasKitでは外れ値が多く見られます。
図には表れていませんが、CanvasKitにおいては連続で計測(一度計測してアニメーションウィジェットを閉じた後に再度計測開始してアニメーションウィジェットを表示)すると、16,000パーティクル以上では必ずWebアプリが落ちました。iPhoneのCanvasKitにおける高負荷の計測データは逐一Webアプリをリロードして得られたものです。この不安定さは大きな問題かと思います。
8.iPhone XR , iOS 14.4 , Chrome (87.0.4280.77) , WebKit
iOSにおいてはWebKit以外でブラウザを作れないので、ChromeであってもSafariと同等の結果となりました。高負荷で落ちるのも一緒です。
9.iPhone 7 , iOS 14.4.1 , Sarari , WebKit
iPhone XRと傾向は変わりませんが、XRよりデバイスのスペックが弱い分、そのまま性能に表れています。なお、iPhone 7は8,000パーティクルから連続計測で落ち始めます。
10.Xperia 5 , Android 10 , Chrome (88.0.4324.93) , Blink
デスクトップ版Chrome同様、CanvasKitで高いパフォーマンスが出ているのがわかります。MacBookの結果と比較してCanvasKitの性能向上が大きく、50%程度高速になっています。
11.Xperia 5 , Android 10 , Firefox (86.1.1) , Gecko
デスクトップ版Firefoxではレンダラーで差がありませんでしたが、Android版(Geckoエンジン)ではChrome同様、CanvasKitで50%程度の性能向上が見られています。
5.まとめ
- Blinkレンダリングエンジンを使用するChrome, EdgeではCanvasKitで30〜40%程度の性能向上が見られます。
- AndroidではChrome(Blink)、Firefox(Gecko)ともにCanvasKitでデスクトップブラウザ以上の性能向上が見られました。
- WebkitおよびServoレンダリングエンジンではほぼ違いが見られません。そもそもWebkitについてはHTMLレンダラーでもBlink系のCanvasKitの性能を上回っています。
- WebKitにおいてはCanvasKitはFPSが不安定になる傾向があります。特にiOSではCanvasKitで負荷がかかるウィジェットを繰り返し表示するとWebアプリがクラッシュします。
結論、iOS版以外のChromeに代表されるBlinkエンジンブラウザにおいてCanvasKitレンダラーは全般的に高速に動作しますが、現時点においてiOSでは不安定でありCanvasKitを使わない方が無難かと思われます。
6.番外
今回の趣旨とは別ですが、検証中にパフォーマンス以外で気がついた点をいくつか挙げておきます。
- 見た目の違い
HTMLとCanvasKitの両者でレンダリング結果の見た目が若干違います。CanvasKitの方がフォントがシャープで影も薄く見えます。どのデバイス、ブラウザでも同様の傾向が見られました。
- CanvasKitはDPRが変わった際に再描画が走らない
MacBookにて、CanvasKitの場合にRetinaディスプレイ⇔外部ディスプレイでブラウザウィンドウを移動すると表示スケールがおかしくなります(おそらくデバイスピクセル比の変化を検知できてないためかと思われます)。HTMLレンダラーでは再描画がかかりますが、CanvasKitでは再描画されませんでした。
- iPhone X系のセーフエリア辺りがおかしい
どちらのレンダラーでもiPhone X系のブラウザでオリエンテーションを変化させて(デバイスを回転して)Webアプリを表示すると、上の例ようにセーフエリアと思われる部分にマージンが発生したりと表示がおかしくなります(レンダラーやブラウザで微妙に挙動が異なります)。上図の状態からポートレート(縦)にすると、コンテンツ表示位置がさらにずれたりします。
今後の改善に期待ではありますが、StableとなってFlutter Webを早々に取り入れようと検討されている方の参考になれば幸いです。
それでは、また。
次世代システム研究室では、アプリケーション開発や設計を行うアーキテクトを募集しています。アプリケーション開発者の方、次世代システム研究室にご興味を持って頂ける方がいらっしゃいましたら、ぜひ 募集職種一覧 からご応募をお願いします。
グループ研究開発本部の最新情報をTwitterで配信中です。ぜひフォローください。
Follow @GMO_RD