Webページの表示の高速化で、画像周りは手を入れにくいなと思いつつも、お手軽で効果があった方法のご紹介です。
画像最適化(1)
まずは表示されるサイズと実際に使用するサイズが同じ(もしくは近い)か確認しました。
(近いと書いたのはレスポンシブにするとデザイン上、画像サイズが画面比率で決定される場合がある為です)
縦横サイズが大きい画像はファイルサイズも大きい場合がほとんどなので、表示に必要なサイズに縦横を調整してサムネイルを生成します。
表示される画像が200x200なのに、ダウンロードされる画像が500x500だと、かなり無駄なので。
少し古い記事だとRetina用に2倍のサイズをsrcに入れるTipsが紹介されていたりしますが、Retina用には srcset
で指定して、 src
には通常サイズを指定するようにしてあります。
画像最適化(2)
画像に不要なデータ(= Exif)が残っている場合があるので、削除しておきます。
image = MiniMagick::Image.open("test.jpg")
image.strip
画像によっては効果があるんですが、元々消えてる画像もあるので画像によって削減できるサイズはまちまちでした。
画像最適化(3)
ここからさらに画像のファイルサイズを削ります。
今回は mozjpeg
を使ってみました。
ImageMagick等で生成されるjpegと比べると同じクオリティでもファイルサイズを小さくすることができます。
mogjpeg をソースインストールしつつ、 Gemで mozjpeg
をインストールしました。
Mozjpeg.compress(
tmp_file,
new_file,
arguments: '-quality 80 -optimize'
)
遅延読み込み(lazyload)
画面外(ファーストビュー外)の画像を遅延読み込みすることで、読み込み完了を早くすることができます。
同様のライブラリはいくつかありますが、今回は lazysizes
を使用してみます。
(最近触っているサイトは、Rails(erb)で imgタグ
が出力される場所もあれば、 Reactで imgタグ
が出力される場所もあるので、どちらも同じ仕組みでlazyloadに対応したかった)
実際はassetsですが、直接読み込めば下記のような感じです。
<script src="/js/lazysizes.min.js"></script>
あとは出力されるimgタグが下記のようになれば、画面外の画像は必要になったタイミングでダウンロードされます。
<img data-src="test.jpg" class="lazyload">
実際は、Retina対応+レスポンシブ対応にしたいので以下のように使用しています。
<img data-src="test.jpg" data-srcset="test.jpg 1x, test2x.jpg 2x" data-size="auto" class="lazyload">
今後
- mozjpegを紹介しつつも、jpgeよりもwebpの方がいいんじゃないかなと思ったりします。
- lazyloadを使っている時に、高速にスクロール(ページの下の方に急激に移動)すると、画像の読み込みが追い付かない場合があるので、これはなんとかしたいです。