マガジン

Unityの圧縮設定とサーバー側の対応:BrotliとGzipの違い

遊びをつくる

執筆にClaudeを使用しています。

大きな荷物で詰まった細い道を測り、軽い部品へ置き換えて流れを整える模型。
記事のテーマをもとに制作したAI生成の写真風イメージ。

Unity WebGLでビルドしたゲームを公開しようとして、サーバーにアップロードしたのにゲームが起動しない、あるいはロードが異様に遅い——という経験をした人は少なくありません。その原因の多くは、Unityが出力したファイルの圧縮形式と、ファイルを配信するサーバーの設定が噛み合っていないことにあります。 この記事では、Unity WebGLビルドの圧縮オプション(Brotli・Gzip・無圧縮)それぞれの仕組みと、サーバー側で何を設定すべきかを整理します。「どの設定を選べばよいか」という判断基準と、主要なホスティング環境での具体的な対応手順を順に説明します。

この記事の目次
  1. UnityのWebGLビルドが出力するファイルと圧縮の関係
  2. BrotliとGzipの違いを判断基準として整理する
  3. サーバー側で必要な設定:ヘッダーとMIMEタイプ
  4. よくある失敗と確認ポイント
  5. 設定選択のまとめと判断の流れ
  6. 次の行動
  7. 参考資料

UnityのWebGLビルドが出力するファイルと圧縮の関係

Unity WebGLのビルド結果は、Buildフォルダの中に.wasm(WebAssembly)・.js(ローダー)・.data(アセット)・.framework.js(フレームワーク)の4種類のファイルが含まれます。これらのファイルは合計で数十MB〜数百MBになることが多く、圧縮しないまま配信するとロード時間が長くなります。

Unityはビルド時にこれらのファイルを事前圧縮する選択肢を提供しています。Player Settings → Publishing Settings の「Compression Format」で設定できます。選択肢は次の3つです。

  • Disabled:圧縮しない。ファイルはそのままの状態で出力されます。
  • Gzip:ビルド時にGzip形式で圧縮したファイルを出力します。拡張子に.gzが付きます。
  • Brotli:ビルド時にBrotli形式で圧縮したファイルを出力します。拡張子に.brが付きます。

ここで重要なのは、「Unityがビルド時に圧縮する」のと「サーバーがリクエスト時に動的に圧縮する」のはまったく別の仕組みだという点です。UnityがGzipを選んでいる場合、サーバーは「このファイルはすでにGzip済みである」とブラウザに正しく伝える必要があります。この伝達を担うのがHTTPレスポンスヘッダーのContent-Encodingです。

BrotliとGzipの違いを判断基準として整理する

Brotli(拡張子.br)はGoogleが開発した圧縮アルゴリズムで、Gzipと比べてファイルサイズをさらに小さくできます。一般に、同じデータに対してBrotliはGzipより10〜20%程度小さいファイルを生成するとされています。Unityの大きなWASMファイルに対しても、その差は数MB単位になることがあります。

ただし、Brotliにはいくつかの制約があります。

Brotliを選ぶべき状況:

  • 使用するホスティングサービスがBrotliのContent-Encoding: brヘッダーを設定できる
  • サーバーの設定に自由度があり、.br拡張子のファイルに対してヘッダーを追加できる
  • ロード時間の短縮を最優先にしたい

Gzipを選ぶべき状況:

  • GitHub PagesやNetlifyなど、設定の自由度が限られたホスティングを使う
  • .htaccessが使えるApacheサーバーを使い、Gzipの設定例を参照して確実に動かしたい
  • Brotli対応が不明なサーバーやCDNを使う

Disabledを選ぶべき状況:

  • サーバー側で動的圧縮(Gzip/Brotliともに)が有効になっており、そちらに任せたい
  • ローカル開発・テスト時に素早く動作確認したい

BrotliはGzipより対応環境が限られます。主要なモダンブラウザはBrotliのデコードに対応していますが、サーバー側がヘッダーを正しく設定していないと、ブラウザはファイルを「通常のテキストやバイナリ」として解釈しようとしてエラーになります。

サーバー側で必要な設定:ヘッダーとMIMEタイプ

UnityがGzipまたはBrotliでビルドしたとき、サーバーには2つの設定が必要です。

1. Content-Encodingヘッダーの付与

ブラウザに「このファイルはGzip(またはBrotli)で圧縮済みだ」と伝えるためのヘッダーです。

  • Gzipの場合:Content-Encoding: gzip
  • Brotliの場合:Content-Encoding: br

2. Content-Typeヘッダーの付与

拡張子が.gzや.brになっているため、サーバーが誤ったMIMEタイプを返すことがあります。元のファイルの種類に応じて正しいMIMEタイプを設定する必要があります。

  • .wasm.gz / .wasm.br → application/wasm
  • .js.gz / .js.br → application/javascript
  • .data.gz / .data.br → application/octet-stream

これらが設定されていないと、ブラウザはファイルを正しく解釈できず、Unityのロード画面で止まったり、コンソールにデコードエラーが出たりします。

Apacheの場合(.htaccess)

.htaccessファイルをBuildフォルダと同じ場所か、その親ディレクトリに置きます。GzipビルドであればUnity公式が提供するサンプルの.htaccessをほぼそのまま使えます。主な記述内容はAddEncodingとAddTypeディレクティブで、.gzおよび.br拡張子に対してヘッダーを付与します。

<IfModule mod_mime.c>
  AddEncoding gzip .gz
  AddType application/wasm .wasm.gz
  AddType application/javascript .js.gz
  AddType application/octet-stream .data.gz
</IfModule>

Brotliの場合はgzipをbrに替え、拡張子を.brに変えた設定を同様に追記します。

Nginxの場合

Nginxではnginx.confまたは該当サーバーブロックの設定ファイルに、locationブロックを使って拡張子ごとにヘッダーを指定します。add_header Content-Encoding gzip;のように記述し、同時にtypesブロックでMIMEタイプを上書きします。Nginxの動的Gzip圧縮モジュール(gzip_static)を使う場合は、ビルド設定をDisabledにして静的圧縮ファイルをサーバーで生成する方法もありますが、UnityのGzipビルドと組み合わせる場合は二重圧縮にならないよう注意が必要です。

GitHub Pagesの場合

GitHub Pagesはカスタムヘッダーの設定ができません。このため、GzipビルドやBrotliビルドをそのまま配信しようとすると、ヘッダーが正しく設定されずにエラーになります。GitHub Pagesに公開する場合は、Compression FormatをDisabledに設定してビルドするのが確実な選択です。ファイルサイズは増えますが、追加設定なしで動作します。

よくある失敗と確認ポイント

症状:ロード画面で止まり、コンソールに「Failed to decompress」と出る→ サーバーがContent-Encodingヘッダーを返していない可能性があります。ブラウザの開発者ツール(Network タブ)でBuildフォルダ内のファイルのレスポンスヘッダーを確認し、content-encodingが付いているか確認します。

症状:コンソールに「MIME type mismatch」と出る→ Content-Typeが正しく設定されていません。.wasm.gzに対してapplication/octet-streamやtext/plainが返っている場合に起きます。

症状:ローカルでは動くがサーバーにアップすると動かない→ ローカル確認にUnityエディターの「Build and Run」を使うとUnity側のローカルサーバーが適切なヘッダーを自動で付けるため、実際のホスティング環境との差異が出ます。必ず本番と同じサーバー構成でテストしてください。

症状:BrotliビルドをApacheに置いたがmod_mimeだけでは動かない→ BrotliのContent-Encoding: brを返すにはmod_headersモジュールも有効になっている必要があります。レンタルサーバーによってはmod_headersが無効になっているケースがあります。サーバーの管理画面やサポートページで確認するか、Gzipビルドに切り替えることを検討します。

設定選択のまとめと判断の流れ

どのサーバーを使うかによって最適な組み合わせは変わります。判断の流れとして次の順番で考えると整理しやすいです。

  1. ホスティング環境がカスタムヘッダーを設定できるかを確認します。できない場合はDisabledを選びます。
  2. ヘッダー設定が可能な場合、サーバーがBrotliに対応しているかを確認します。対応しているならBrotliが最もファイルサイズを小さくできます。
  3. ApacheでBrotliを使う場合はmod_headersの有効可否を確認します。不明な場合はGzipの方が設定例が多く安定しています。
  4. 設定後は必ずブラウザの開発者ツールでレスポンスヘッダーを目視確認します。Unityのロード画面を見ているだけでは設定ミスに気づきにくいです。

次の行動

まずブラウザの開発者ツールのNetworkタブを開き、公開済みのBuildフォルダ内ファイルにcontent-encodingヘッダーが付いているかを確認してください。付いていない場合は、使用しているサーバーの種類に合わせてこの記事の手順を参照しながらヘッダー設定を追加します。設定が完了したら、ゲームを最初からロードし直してコンソールにエラーが出ないかを確認します。アソバースへの投稿を検討している場合は、ZIPファイルにBuildフォルダを含めてアップロードする前に、公開先サーバーの圧縮設定が正しいかをローカルテスト環境で確かめてから進めてください。

参考資料

  • Unity公式ドキュメント「WebGL: Deploying compressed builds」
  • MDN Web Docs「Content-Encoding」
  • Apache HTTP Server公式ドキュメント「mod_mime」「mod_headers」
  • Nginx公式ドキュメント「ngx_http_gzip_static_module」