2015年に開催したCreateJS勉強会(第6回)でのライトニングトーク「オーディオスプライトを使った音声ファイルの最適化」の発表内容を記事としてまとめました。音声を扱ったHTML5コンテンツにおけるCreateJSの最新機能「オーディオスプライト」の必要性と使い方を本記事で紹介します。
ウェブページではファイルの読み込み数を減らすことが必要
ウェブページを見る時や作る時、そのページでどのくらいのファイルがダウンロードされているかを気にしていますか? CSS・JavaScript・画像・音声ファイル等、ウェブページでは必要なファイルが多くなりがちです。ファイル数が多いとファイルをダウンロードする時間が増え、その分だけページの表示速度が遅くなります。ページの表示速度が遅くなると、その分だけユーザーの離脱率が上がります。
Amazonはページの反応が0.1秒遅くなると、売り上げが1%ダウンするGoogleのページ反応が0.5秒遅くなると、アクセス数が20%ダウンする
つまり、ウェブ制作者はファイルの読み込み数をできるだけ減らしてページの表示速度を上げる必要があるわけです。
複数のファイルを1つにまとめる
では、ファイルの読み込み数を減らすためにはどうしたらよいのでしょうか? 複数のファイルを1つの大きなファイルとして結合すればよいのです。CSSやJavaScript、画像ファイルを1つのファイルに結合し、読み込み数を減らすという手法がウェブ制作現場ではよく用いられます。とくに、画像ファイルを1つにまとめたものを「スプライトシート」といいます。
たとえばFacebookでは、ロゴやアイコンなどを結合し、画像ファイルの読み込み数を減らしています。実際に使用されている画像は下記です。背景は透明ですが、ロゴやアイコンの白色が目立ちやすいように筆者が背景色を設定しました。
複数の音声ファイルは「オーディオスプライト」を使って1つにまとめられる
ならば、音声ファイルの読み込み数を減らすにはどうすればよいでしょうか? 実は音声ファイルもスプライトシートと同じように複数のファイルを1つのファイルにまとめることができます。これを「オーディオスプライト」といいます。スプライトシートの音声ファイル版です。必要に応じてオーディオスプライト内の音を選んで再生して使います。
SoundJSを使うとオーディオスプライトを 手軽に使える
オーディオスプライトの実装は面倒だと思われるかもしれませんが、SoundJSを使えば手軽に使えるようになります。SoundJSはCreateJSのライブラリ群の1つで、シンプルな命令を使ってHTML5の音の制御ができます。最新バージョン0.6.0でオーディオスプライト機能がサポートされました。SoundJSでオーディオスプライトを使う際は、音声ファイルとマニフェストというデータが必要です。
音声ファイルの作成
音声ファイル制作時に気をつけたいポイントは次の2点です。
- 各音データの間に0.3秒〜0.5秒程度の間隔を設けて作成する 連続して音を鳴らした時に、前後の音が鳴ってしまうのを防げます。
- 可変ビットレートで作る ogg形式やmp3形式の音声ファイルを作る時は「[可変ビットレート](http://www.sophia-it.com/content/VBR)」をオプションとして指定できます。可変ビットレートでファイルを作成しておくと、間隔を設けて音声ファイルを作成したとしてもファイルサイズが肥大しません。
マニフェストの準備
オーディオスプライトを扱うためのデータである「マニフェスト」をJavaScriptで記述します。マニフェストにはオーディオスプライトのファイル名や同時に鳴らす音の数、個別の音の情報(ID名、開始時間、音の長さ)が記載されています。具体的には以下のようなデータです。
[
{
src: "sounds/150903.ogg",
data: {
channels: 5,
audioSprite: [
{
id: "se_0",
startTime: 0,
duration: 2600
},
{
id: "se_1",
startTime: 4000,
duration: 2600
},
{
id: "se_2",
startTime: 8000,
duration: 2600
}
]
}
}
]
オーディオスプライトとマニフェストデータを使って音を鳴らすシンプルなデモを作りました。具体的なJavaScriptのコードは下記を参照していただければと思います。
オーディオスプライトを使うとどれくらいの違いが出るのか?
では、オーディオスプライトを使った場合と使わない場合でどれくらい読み込み時間に差が出るのでしょうか? オーディオスプライトを使った場合、使わない場合の2パターンにおいてデモを作って検証しました。デモの内容は下記です。
- 音声ファイルの読み込み後、再生ボタンを押すことでコンテンツが開始する
- BGMがループする
- フリックするとパーティクルが発生し、21種類の音が流れる
- ページ左下に読み込み時間が表示される(キャッシュを消すとわかりやすいです)
オーディオスプライトを使わないデモ
まずはオーディオスプライトを使わない場合のデモです。BGM、21種類の音合わせて22個の音声ファイルを読み込んでいます。総ファイルサイズは3.2MB、読み込み時間は3.1秒でした(ogg形式、約40MbpsのWi-Fi回線)。
オーディオスプライトを使ったデモ
続いてオーディオスプライトを使った場合のデモです。BGMのループ、フリック時の21種類の音再生合わせて、前述のデモと表現上の差異がないことがわかります。
オーディオスプライトを使うと読み込み時間が短くなった
気になる読み込み時間はどうなったのでしょうか? 結果は下図の通りです。ファイル数は22個から1個へと減少し、読み込み時間は0.9秒と300%も高速化しています。ファイルサイズも0.2MB減少しています。表現に差がなく、読み込み時間が短くなり、ファイルサイズが小さくなるという結果が得られました。実際に表示してみるとわかりますが、オーディオスプライトを使ったバージョンの方が体感的にもかなり早いです。
]
オーディオスプライトのデメリット
一見万能なオーディオスプライトですが、デメリットもあります。
- ファイルの更新の手間がかかる たとえば上記の音を1種類変更した場合、音声ファイルを手動で作り直し、マニフェストファイルを書き換えるという手間があります。(これはタスクランナーを使用して上手く自動化できないか現在調査中です。)
- HTML Audio要素の相性が悪い HTML5で音を鳴らす方法としてWeb Audio APIと[HTML Audio要素](https://developer.mozilla.org/ja/docs/Web/HTML/Element/audio)の2種類があり、SoundJSで音を鳴らす場合、環境に応じてどちらかの方法が自動で選択されます。このうち、HTML Audio要素を使った場合は上手く再生されません。Web Audio APIの方が高度な音声表現が可能で、最新のブラウザではほとんど使えるのですが、Internet Explorer 11とAndroid 4以下の標準ブラウザ等一部のブラウザではHTML Audio要素しか使えません(※)。これらのブラウザが対象の場合には代替手段を準備する必要があります。
※ Internet Explorerの後継ブラウザMicrosoft Edgeや、Android 5以降の標準ブラウザではWeb Audio APIが使用可能です(Can I use)。
まとめ:勉強会で伝えたかったこと
今回伝えたかった内容は下記の4点です。
- 複数の音声ファイルはオーディオスプライトを使って1つにまとめることができる
- SoundJSを使うとオーディオスプライトを手軽に使える
- オーディオスプライトを使うとファイルの読み込み時間が短くなる
- デメリットもあるので使用シーンを吟味する
勉強会後のアンケート結果を見ると、「オーディオスプライトをはじめて知った」「パフォーマンスが大きく向上していて驚いた」という声が多かったです。CSS、JavaScript、画像の最適化とともに、音声ファイルの最適化も意識していきましょう。今回のデモはGitHubにて公開してます。よろしければご確認くださいませ(ソースコード)。