ウェブアプリのWebGLに関するベストプラクティス
WebGLは、GPUを利用して高いパフォーマンスを実現するグラフィックスライブラリです。高品質のビジュアルと複雑なアニメーションをブラウザに直接描画できます。このライブラリにより、ブラウザでOpenGL ES(低レベルの3DグラフィックスAPI)が利用可能になります。追加のインストール、拡張機能、プラグイン、アドオンは必要ありません。WebGLは標準に準拠しているため、ほとんどのブラウザで、さまざまなライブラリ、一般的なシェーダー、ゲームエンジンなどのグラフィックスエンジンがWebGLをサポートしています。
VegaウェブアプリでのWebGLの動作
Vegaウェブアプリはv132で、WebGL 2.0をサポートしています。Vegaでは、ChromiumのWebGLレイヤーがカスタマイズなしで使用されます。これは、AndroidのWebViewやLinuxのChromiumと同じように機能します。
デバイスでWebViewアプリを読み込む際に、ソースURIとしてhttps://webglreport.com/?v=2(英語のみ)を指定すると、追加の詳細情報を確認できます。
Platform: Linux x86_64
Browser User Agent: Mozilla/5.0 (Linux; OS 1.1; AFTCA002 userdebug/1343; wv) AppleWebKit/537.36 (KHTML, like Gecko) Mobile Chrome/118.0.5993.159 Safari/537.36
Context Name: webgl2
GL Version: WebGL 2.0 (OpenGL ES 3.0 Chromium)
Shading Language Version: WebGL GLSL ES 3.00 (OpenGLES GLSL ES 3.0 Chromium)
Vendor: WebKit
Renderer: WebKit WebGL
Unmasked Vendor: Mesa
Unmasked Renderer: Mali-G310 (Panfrost)
Antialiasing: Available
ANGLE: No
Major Performance Caveat: No
サポートされている拡張機能
以下は、WebGLでサポートされている拡張機能の一覧です。
- EXT_color_buffer_float(英語のみ)
- EXT_color_buffer_half_float(英語のみ)
- EXT_disjoint_timer_query_webgl2(英語のみ)
- EXT_float_blend(英語のみ)
- EXT_texture_filter_anisotropic(英語のみ)
- EXT_texture_norm16(英語のみ)
- OES_texture_float_linear(英語のみ)
- WEBGL_compressed_texture_astc(英語のみ)
- WEBGL_compressed_texture_etc(英語のみ)
- WEBGL_compressed_texture_etc1(英語のみ)
- WEBGL_debug_renderer_info(英語のみ)
- WEBGL_debug_shaders(英語のみ)
- WEBGL_lose_context(英語のみ)
- WEBGL_multi_draw(英語のみ)
VegaでWebGLを使用するための戦略
これらの戦略は、パフォーマンスを高めるためにWebGLライブラリを使用するゲーム、TVアプリ、生産性向上アプリに適用されます。DOM/HTMLのレンダリングとメモリ管理の方法はブラウザによって管理されるのに対して、WebGLは直接実装する必要があります。次の一般的なガイドラインに従ってください。
- 複雑な計算を簡素化し、メモリを効率的に管理します。JSとC/C++間の変換はできるだけ直接的にします。
- テクスチャ、アセット、オブジェクトのサイズを削減または制限します。
- 既存のブラウザ設定、GPUオプション、ハードウェアに最適化されたブラウザツールやライブラリを再利用します。または、アプリに合わせて細かく調整できるブラウザ設定のみを再利用することもできます。
キャンバスへのビデオ表示の回避
ビデオ用のPixiJS API(英語のみ)のように、WebGLにビデオを組み合わせることは避けます。代わりに、HTMLのvideo要素や、その他のウェブベースのビデオプレーヤーライブラリを使用します。VegaはプライベートGPUバッファーを使用してビデオを直接再生するので、ビデオフレームがWebGLテクスチャとして抽出されることはありません。
ドローコールの削減
テクスチャアトラス、頂点バッファーオブジェクト(VBO)、インデックスバッファーオブジェクト(IBO)、インスタンス化などの手法を使用して、複数のオブジェクトを1回のドローコール(バッチ処理)にまとめます。インスタンス化とは、同じオブジェクトの複数のインスタンスをレンダリングすることです。OpenGL ESでは、1フレームあたりのドローコール数を500回未満にしてください。
描画の実行は、setTimeoutとuseEffectではなくrequestAnimationFrameから行います。useEffectやuseMemoを使用する場合は、requestAnimationFrameが使用する値を更新することで、描画されるオブジェクトを変更します。可能であれば、描画したオブジェクトや描画に使用した方程式をキャッシュして、その処理にかかる時間を短縮します。
テクスチャの最適化
テクスチャのサイズを必要最小限の解像度に変更します。圧縮テクスチャ形式(DXTやETCなど)を使用し、ミップマップを取り入れます。テクスチャアトラスを使用することでも、ドローコールとメモリ使用量を削減できます。
複雑なアルゴリズムの簡素化
- 可能な場合は、
highp floatではなくhalfやfloatなどの低精度のデータ型を使用します。 - シェーダーの複雑さと、必要となる計算の回数を最小限に抑えます。
- powやsinなどのリソース負荷の高い関数の代わりに、ルックアップテクスチャを使用します。
- ライトとシャドウが多すぎると、パフォーマンスに影響を及ぼします。ベイクされたライティング(事前レンダリング)を使用するか、リアルタイムライティングを簡素化することを検討してください。
カリングとLODの実装
可能な場合は、LOD、視錐台、オクルージョンカリングのようなアルゴリズムを使用します。滑らかさを向上させるために、詳細レベルを下げ、不可視のオブジェクトは描画しないようにします。相対LODは、表示するポリゴンが多いときに、ポリゴンの品質を下げることで高負荷に対応します。
効率的なメモリ管理
- テクスチャ、バッファー、プログラムなどの不要になったWebGLオブジェクトは廃棄します。
- メモリの使用状況を注意深く管理して、不要な割り当てと割り当て解除を防ぎます。
- 可能な場合は、クラスではなく構造体(TypeScriptインターフェイス)を使用します。
- 頻繁に使用されるメソッド内では、クラスの再インスタンス化、文字列の連結、計算量の多い方程式を実行しないようにします。
- メモリを事前に割り当て、リストの代わりに配列を使用し、可能な場合はポインターや参照のような共有リソースを使用します。
- オブジェクトプーリングを実装してメモリの断片化を抑えます。
ファイル管理
- スプライトやその他の画像アセットをできるだけ再利用して、ファイルの読み込み時間を短縮します。
- ライブラリ内の既存のアセットバンドルシステム、圧縮やバンドルを行うゲームシステムを活用します。
- ファイルの読み込みには、非同期処理または並列処理を使用します。
- MP3やOGGなどの圧縮オーディオ形式を使用します。同じオーディオを繰り返し再生する場合は、読み込むファイルの数が多くなりすぎないようにします。
- サウンドエフェクト(SFX)用のオーディオファイルを連結して、読み込み時間とメモリ使用量を最適化します。
- サウンドエフェクトごとに個別のオーディオファイルを使用するのではなく、時間を指定する方法でオーディオを再生することを検討します。
// 複数のファイルを使用するのではなく、1つのmp3またはoggファイルを再生時間を変えて使用します。 // これにより、読み込み時間とメモリ使用量が最適化されます。 // 特に同じオーディオが頻繁に再生される場合に便利です。 // // SFXやバックグラウンドオーディオに便利です。 this.playAudio(2.9088, 0.1437);
ハードウェアアクセラレーション
ハードウェアアクセラレーションはデフォルトでオンになっています。ブラウザでハードウェアアクセラレーションをトリガーするために使用されるCSSによって、パフォーマンスが向上することはほとんどありません。
// ハードウェアアクセラレーションを強制しても、効果は望めません
document.body.style.transform = 'translateZ(0)';
document.body.style.backfaceVisibility = 'hidden';
以下のコードを読み込み時に使用すると、パフォーマンスが少し向上することがあります。powerPreference設定が「high-performance」の場合、エネルギー効率よりもパフォーマンスを優先するようにブラウザに指示します。アンチエイリアスのようなほかの設定によっても、レンダリング時のGPU処理が削減されます。アプリによっては、アンチエイリアスを無効にしても表示上はそれほど気にならない可能性があります。低速のデバイスでもfailIfMajorPerformanceCaveat: falseを使用するオプションは、結果が遅くてもコードを同じように実行する場合に便利です。
// WebGLコンテキストを最適化します。
const canvases = document.querySelectorAll('canvas');
canvases.forEach(canvas => {
const ctx = canvas.getContext('webgl', {
antialias: false,
powerPreference: 'high-performance',
failIfMajorPerformanceCaveat: false,
});
});
ハードウェアアクセラレーションはデフォルトで有効になっていますが、追加設定を微調整するとアプリでパフォーマンスを強化できます。微調整は、リソースの少ないデバイスでVegaウェブアプリを実行する場合にWebGLの最適化に役立ちます。
状態変更の最小化とブロッキング呼び出しの回避
- 状態の変更回数を最小限に抑えます。これらを最小限に抑えるには、異なるシェーダープログラム、テクスチャユニット、レンダリングターゲットを切り替える方法などがあります。
getError()やgetParameter()などのブロッキング呼び出しはパフォーマンスに影響するため、メインスレッドで実行しないようにします。requestAnimationFrameを使用しないときはgl.flush()を使用して、ブラウザでWebGLコマンドがより迅速に実行されるようにします。
関連トピック
Last updated: 2026年2月5日

