データを圧縮転送してブラウザ版のティラノスクリプト製ゲームの通信量を減らす

サーバー

先日、こちらの記事でえもふりのモデルを圧縮してから転送する方法が紹介されているのを目にしたので、早速試してみました。

参考 Webサーバーからemtbytesを圧縮転送する

しかし、E-moteのロゴを表示するタイミング(あのロゴもモデルなのでモデルを表示すると固まることになる)でなぜかフリーズしてしまい、うまく行かなかったので別の方法をとることにしました。

そのときの記録です。

サーバ環境はmixhost(LiteSpeed)です。

ちなみにLiteSpeed系のサーバはさくらサーバなどのApache系と大部分が似ているので、同じ記述ができると思います。

スポンサーリンク

gz圧縮転送をやってみる

まずE-mote公式で紹介されている方法を試したがダメだった

ちゃんとロゴなどemtbytesファイルはすべてgz形式に圧縮し、ゲームプロジェクトのえもふりプラグインの該当フォルダにアップロードしました。

そして.htaccessに以下の記述を追加し、こちらもルートディレクトリにアップロードします。

RewriteEngine On

RewriteCond %{HTTP:Accept-Encoding} gzip
RewriteCond %{REQUEST_URI} (\.emtbytes)$
RewriteCond %{REQUEST_FILENAME}.gz -s
RewriteRule .* %{REQUEST_URI}.gz [L]

<FilesMatch "\.emtbytes\.gz">
ForceType application/octet-stream
</FilesMatch>

いざ、ゲームのページにアクセス。

すると冒頭に書いたとおり、ロゴを表示しようと画面が真っ白になったタイミングで固まります。

コンソールをのぞいてみると、なにやらエラーがたくさん。

背景が白い英文をGoogle翻訳を通してみるとこうなります。

VM1655:24メモリ配列を拡大できません。 (1)現在の値100663296より大きいXを持つ-s TOTAL_MEMORY = Xでコンパイルする、(2)実行時にサイズを調整するが最適化を防止する-s ALLOW_MEMORY_GROWTH = 1でコンパイルする、(3)Module.TOTAL_MEMORYをaプログラムが実行される前の値が大きい、またはmallocがこの中断の代わりにNULL(0)を返すようにするには、-s ABORTING_MALLOC = 0

詳しい原因は僕にはわかりませんでした。

LiteSpeed系のサーバはApache系サーバと同じモジュールが使えるはずなので、イケると思ったのですが……。

なんとなく意味を汲み取ってみると「TOTAL_MEMORYが足りない。100663296よりもさらに必要だ」的なことを言われているようです。

たぶんgzファイルを展開処理する際にメモリを食いまくっているのかな?(真偽不明) とか思ったので、この数値をいじって20倍くらいにしたところ今度は

motionDriver.cpp(2414): RegisterArchive(): this psb file is not motion file.

と言われてしまいました。

つまり「これはモーションファイルではありません」という意味です。これはおそらくブラウザそのものが吐くエラーではなく、E-moteのプラグインのドライバが吐き出しているエラーです。

いやいや、そんなわけないだろ! と思いましたが、違うというなら仕方がありません。

もしかしたら圧縮時にファイルが壊れているのかもしれないと思い、超圧縮ではなくもう少し軽めな圧縮を試しましたが、残念なことに結果は同じでした。

gzip転送についてちゃんと調べてみたらうまく行った

あらかじめ圧縮するgzip転送についていろいろ調べてみたところ、以下のような書き方でCSSやJSを圧縮転送する方法が見つかりました。

RewriteEngine on
RewriteCond %{HTTP:Accept-Encoding} gzip
RewriteCond %{REQUEST_FILENAME}\.gz -s
RewriteRule ^(.+) $1.gz

<FilesMatch "\.css\.gz$">
ForceType text/css
AddEncoding x-gzip .gz
</FilesMatch>
<FilesMatch "\.js\.gz$">
ForceType application/x-javascript
AddEncoding x-gzip .gz
</FilesMatch>

Header append Vary Accept-Encoding env=!dont-vary

上の数行はE-mote公式ブログで紹介されている記述と大差ありません。(E-mote公式ブログの記述はemtbytesファイルだけ圧縮転送する設定になっている)

E-mote公式の記述に足りないのは「AddEncoding x-gzip .gz」という記載と「Header append Vary Accept-Encoding env=!dont-vary」という記載です。

というわけで、上記を参考に以下のように書き換えたところエラーが出なくなりました。

RewriteEngine on
RewriteCond %{HTTP:Accept-Encoding} gzip
RewriteCond %{REQUEST_FILENAME}\.gz -s
RewriteRule ^(.+) $1.gz

<FilesMatch "\.emtbytes\.gz$">
ForceType application/octet-stream
AddEncoding x-gzip .gz
</FilesMatch>

Header append Vary Accept-Encoding env=!dont-vary

「Header append Vary Accept-Encoding env=!dont-vary」はgz圧縮転送に対応していないブラウザ対策です。説明すると長くなってしまうので、詳しくはググってください。

せっかくなのでキャッシュの設定もしていく

転送量を少なくするのもいいですが、ブラウザゲームとなると何度も同じページを訪れてくれる可能性が高いため、転送回数そのものを減らすことも有効です。

いわゆるキャッシュというやつです。

キャッシュする時間を設定

データのキャッシュは設定しなくても自動的におこなってくれますが、設定したほうがさらに効率よくデータ転送を管理できます。

たとえばあまり更新しないデータはキャッシュ時間を1年のような長めに設定し、頻繁に更新するデータは1日に設定するなどです。

ブラウザは手元にキャッシュがあると「このキャッシュデータはいつまで有効なのか」をサーバ側に問い合わせ、有効期限が切れていなければそれを使用します。

今回の設定ではその問い合わせさえもカットするので、処理が高速になります。

#フォントのcontent-typeの追加
AddType application/vnd.ms-fontobject .eot
AddType application/x-font-ttf .ttf
AddType application/x-font-opentype .otf
AddType application/x-font-woff .woff
AddType image/svg+xml .svg

#E-moteのcontent-typeの追加
AddType application/octet-stream .emtbytes

#ブラウザキャッシュの設定
ExpiresActive On
ExpiresByType text/css "access plus 1 days"
ExpiresByType image/gif "access plus 1 weeks"
ExpiresByType image/jpeg "access plus 1 weeks"
ExpiresByType image/png "access plus 1 weeks"
ExpiresByType application/x-javascript "access plus 1 weeks"
#フォント
ExpiresByType application/vnd.ms-fontobject "access plus 1 year"
ExpiresByType application/x-font-ttf "access plus 1 year"
ExpiresByType application/x-font-opentype "access plus 1 year"
ExpiresByType application/x-font-woff "access plus 1 year"
ExpiresByType image/svg+xml "access plus 1 year"
#oggファイルとE-mote
ExpiresByType audio/ogg "access plus 1 year"
ExpiresByType application/octet-stream "access plus 1 weeks"

これはティラノスクリプトのために書いている記事なので、一応わかりやすくE-moteファイルとoggファイルだけは切り分けました。

ほぼ変更することがないと思われる音楽とフォントは1年に設定しています。

最終的に完成する記述

圧縮転送の設定と合わせ、最終的に完成する記述がこれです。

#フォントのcontent-typeの追加
AddType application/vnd.ms-fontobject .eot
AddType application/x-font-ttf .ttf
AddType application/x-font-opentype .otf
AddType application/x-font-woff .woff
AddType image/svg+xml .svg

#E-moteのcontent-typeの追加
AddType application/octet-stream .emtbytes

#ブラウザキャッシュの設定
ExpiresActive On
ExpiresByType text/css "access plus 1 days"
ExpiresByType image/gif "access plus 1 weeks"
ExpiresByType image/jpeg "access plus 1 weeks"
ExpiresByType image/png "access plus 1 weeks"
ExpiresByType application/x-javascript "access plus 1 weeks"
#フォント
ExpiresByType application/vnd.ms-fontobject "access plus 1 year"
ExpiresByType application/x-font-ttf "access plus 1 year"
ExpiresByType application/x-font-opentype "access plus 1 year"
ExpiresByType application/x-font-woff "access plus 1 year"
ExpiresByType image/svg+xml "access plus 1 year"
#oggファイルとE-mote
ExpiresByType audio/ogg "access plus 1 year"
ExpiresByType application/octet-stream "access plus 1 weeks"


#圧縮転送の設定
RewriteEngine on
RewriteCond %{HTTP:Accept-Encoding} gzip
RewriteCond %{REQUEST_FILENAME}\.gz -s
RewriteRule ^(.+) $1.gz

#E-mote
<FilesMatch "\.emtbytes\.gz$">
ForceType application/octet-stream
AddEncoding x-gzip .gz
</FilesMatch>

Header append Vary Accept-Encoding env=!dont-vary

1回目の転送はgz圧縮転送のおかげでそれなりに高速、ブラウザキャッシュのおかげで2回目以降は爆速です。

コメント