css 1枚にまとめた複数の画像を使いまわす

最近ではあまり気にもならなくなりましたが、画像の読み込みについて昔は親の敵のように圧縮してみたりしてブロックノイズバリバリの画像なんかはたくさんあったわけですが、最近では回線の速度も向上してかなり巨大な画像でもスムーズに読み込めるようになりました。
それでもGoogle先生は言うのです!

サイトの読み込み速度を上げなさい、スコアが出ませんよ

と。

確かに、写真とかだとしょうがない場合もあります。サムネイル化して軽い画像を先に表示しておいてクリックすることで本来の画像を見せると言うのもひとつの方法でしょうし、キャッシュさせて二度目からはローカルから読み込むというのも方法でしょう。
ただ、キャッシュさせたくない場合もあります。むしろ、回線速度の向上の恩恵でキャッシュなくてもそこそこ速く読み込める場合も多々あります。
動的にページが切り替わったり、表示する画像が毎回異なったり、あるいは結構な頻度でデザインが変わったりして、キャッシュされると反映されないので困ると言う場合もあるでしょう。

色々と悩みながら、ページを速く読み込ませるためにはオプティマイズ(最適化)か・・・と、ロスレスで圧縮してみてもそんなに速度が向上するわけではありません。しないよりはマシですが。

しかし、Googleなんかも確かGoogle+とかのアイコンなんかはそうだったように記憶しているのですが、1つ1つアイコンを作って表示させるのではなくひとまとめにして、それを使いまわしていたりするわけです。
そうすると、1つが10KBぐらいだとして、10個集めたら100KBになるかというとそういうわけではありません。大体の場合は100KB以下になるでしょう。すると、その複数をまとめた画像を1回読みこませれば、あとは使い回しできるわけですからアクセス(リクエストに対する応答)の回数も減り、結果的に速度が向上すると言うのが見込めます。
ではどうやってするんだ?ということなのですが、例えば

こんな感じにやってみました。わかりやすいように、リンクをクリックするとアニメーションで動作するので1枚の画像であることが理解してもらえると思います。もちろん、本来はjQueryは必要ありません。その例として、左側にリスト表示させているものがそれです。
一番下には元になっている画像も表示しておきました。(今しがたFirefoxで見てみたらアニメーションしなかったので、何かしらfirefoxに対して設定ミスがあるかもしれません。Chrome(Iron)であれば大丈夫です 直しました)

どういうことをしているかというと、まず表示したい枠を作って、そこの背景として画像を読み込みます。
で、別でclassを作って画像の位置を指定しているだけなのです。

まず今回用意した画像ですが、width:125px, height:160pxの画像が4つで、それらをwidth:500px,height:160pxの画像にまとめてあります。photoshopなど画像を加工できるソフトで、スナップ機能(要素に吸い付くアレ)があれば、元の画像サイズが同じものを用意する場合は簡単に並べられます。
無料のものであればGIMPなどを利用しても良いかと思います。Inkscpeとかでもできなくはないでしょう。

別に元の画像を同じサイズにする必要はないのですがしておいた方が設定が楽なので、しておくことをオススメします。
今回の画像のように125刻みで500までのものであれば、Xの値だけを設定すれば表示できます。大島優子の位置だと、2つ目なのでXが0の時一番左の横山由依が表示され、-125pxすると、大島優子が出てきます。このような設定をそれぞれ作るわけです。
たくさんのデータがある場合は、数値化したものをjsonとかにまとめて、それを読み込みjQueryで処理するのが良いのかもしれませんし、PHP側でしても良いかもしれません。
今回は、

と設定してあります。jQueryでは、何をしているかというと、リンクがクリックされたらhrefの内容を取り出してswitchで分岐、表示する所にそれぞれのclassを追加して表示すると言うだけの話です。
単純に表示するだけであれば、左側縦に並んでいるように、表示する場所と、画像の位置をまとめたクラスを同時にIDとclassとして設定すればいけます。

応用編として、マウスオーバーすると変化するようなものもこれを利用して作ることができます。上下、あるいは左右に元の画像と変化する画像を並べてbackgroundの画像の位置を変えてやればよいわけです。こういうのは写真とかよりもアイコンなどの方が実用的かもしれませんね。

また別の話で。
大きな画像などには向かないかもしれませんが、例えば、
これは、中身的に

こんな感じになっています。何でもバイナリデータよりは3割増しぐらいになるそうですが、HTTP リクエストを減らせるメリットがあるということ。これもimgで読み込むとhtmlのソースがエライことになって読みなおすのが大変なので、cssのbackground-image等で読み込ませるのが良いかと思います。

こういうのはdata URI scheme(スキーム)といいまして、現在ではobject (images only)、img、input type=image、link、cssではbackground-image、background、list-style-type、list-styleなどのurlが読み込める所に使用することができます。ブラウザもIE8以上とモダンブラウザはたいていサポートしているので、小さいアイコンなどではこちらを利用する方が軽くなる場合もあるでしょう。

どちらにしても、画像をいくつも読み込むよりはHTTP リクエストを減らすことによって、サイトの読み込みスピードを上げられる・・・かもしれません。
今となって思い返せば、これって昔のファミコンやPCゲームには当たり前のようにあったスプライトデータの利用なんですよね。キャラクターテーブルと言っていたような記憶がありますが、アドレスのxxxx番からxxxxまでは自機データとか色々設定して、そういうツールを自分で本とかを見ながら打ち込んで作るわけですよ。
で、キャラクターデータを作った頃にはせいも根も尽き果てて、肝心のゲームプログラムには進めなかったりと言うこともありました。ただ、そういうのを乗り越えて自分で打ち込んだゲームにキャラクターが表示されてそれをキーボードで操作できた時の感激は強烈なものがありました。

最近ではドラクエⅠとかでずっと前しか向いてない主人公キャラとかダッセー・・・なんて声も聞こえてきますが、あれ作るのも結構大変なんですよ。方眼紙に色つけて作ったりして、実際表示させたら何かおかしくて、どのドットだよ!なんて色々と確かめたりしたり。ファミコンのゼビウスですら感動したものです。

スマホのゲームですら3Dでグリグリできたりする時代ですから遠い昔の話といえばそうですが、ゲームというより、何か作ってる感じがとてもおもしろい時代でした。

スポンサーリンク

シェアする

フォローする