2020年3月30日 更新

【表示高速化】JAMstackにおける画像読み込みのおすすめTIPS【UX向上にも繋がる】

「JAMstackの画像読み込み、どうしていますか・・・?」

今回は画像表示に関するTIPSをご紹介したいと思います。
冒頭で問いかけた通り、JAMstackにおける画像表示方法のご紹介です。

このページをご覧になっている方はJAMstackの仕組みをご存知の事と思います。
もしまだの方はこちらをご覧ください。

さて本題に戻ります。

「JAMstackの画像読み込み、どうしていますか・・・?」

JAMstackは事前にビルドするためブラウザ情報は使用できませんよね。
そこで課題になってくるのが下記です。

静的ジェネレートした画像サイズは画面幅の考慮が出来ない・・・

そうです。どのサイズで画像を表示すれば良いのか、ビルド時には考慮できないのです。
かといって、分からないからサイズ指定しないでおいて、クライアント側で画面幅に応じて画像サイズ指定すれば良いのでは?と思うかもしれません。
しかしその方法では、サイズ指定されていない画像が読み込まれ、その後サイズ指定された画像が読み込まれるといった処理フローとなり余計に通信が発生し逆効果になります。ならばクライアント側でサイズ指定しないほうがまだましです。もしくは静的ジェネレート時に画像描画せず、クライアント側で描画するようにしたほうが良いでしょう。
分かりやすくまとめました。普通に考えると下記3つの方法があがると思います。

方法① 画像サイズ指定しない。

画像によっては非常にサイズが大きくなりますね。初期表示が遅くなります。論外。

方法② 静的ジェネレート時は画像サイズ指定せず、描画時に画像サイズ指定する。

重い画像が読み込まれた後に最適化された画像が読み込まれます。①よりも重くなってしまいます。
こんなイメージです。

サイズの大きい画像が2度読み込まれるのが分かると思います。無駄ですね。

方法③ 静的ジェネレート時は画像表示せず、描画時にサイズ指定された画像を表示する。

一見良さそうに見えますが、初期表示は画像が表示されない状態なので画像表示が遅くなります。また実装の仕方によっては画像のDOM生成されず、クローラーがどのタイミングをINDEXするかでSEO的にマイナスになる場合があります。

どれもパッとしないなあ、と個人的には感じました。
そこで下記の方法に辿り着きました。

画像サイズが小さい状態で静的ジェネレートし、クライアント側でレスポンシブな画像サイズで再描画する

小さな画像で表示された後に正しいサイズの画像で上書きする、という手法です。
下記のイメージを見ていただくとどんな風に表示されるか分かりやすいかと思います。例は当ブログのTOPページです。

静的ジェネレートした際の表示


ブラウザ描画後の表示



見て頂けると分かる通り、最初にボヤッと表示された後にハッキリと表示される流れになります。
また、ネットワークの通信は下記のイメージになります。

ネットワーク通信の様子



前項と同様に2度読み込まれるのですが、初回のロードサイズが小さい!
こうしたことにより、

  • 初期ロードサイズの軽量化
  • SEOへの影響はほぼなし
  • 早めにボヤッと表示されることによるUXの向上

のメリットが見込まれます!
(SEO影響ですが、どちらの画像がINDEXされるかで画像検索に影響が出るかもしれませんが・・・)

もしメリットあると感じた方は試してみてくださいね。
表示される画像サイズが定まっている場合に有効な手段だと思います。
最後に、Nuxt.js及びmicroCMSを用いた際の実装方法のご紹介です。

Nuxt.js及びmicroCMSを利用した際の実装方法

microCMSでは画像URLにクエリパラメータを付与することでロードする画像サイズを調整できます。
よって、下記のように記述すると実現できます。

<template>
 <div class="image-container">
  <img :src="dispImage" />
 </div>
</template>
<script>
export default {
 data() {
  const baseImage = 'https://your-domain.com/your-image.jpg'
  return {
   baseImage,
   dispImage: baseImage + '?fit=crop&w=50&h=40'
  }
 },
 mounted() {
  const query =
   window.innerWidth >= 512
    ? '?fit=crop&w=600&h=480'
    : '?fit=crop&w=300&h=240'
  this.dispImage = this.baseImage + query
 }
}
</script>


data()部分で初期表示時の小さいサイズを指定し、mounted()部分で画面幅に応じて画像を読み込ませる事がミソです。
アスペクト比は初回と2回目で同じにしておきましょう。
これでJAMstack流モヤっとロードの完成です!👏

では今回はこの辺で失礼します。