• 活用ブログTOP
  • 【カスタムブロック】ページ内の画像を最適化!一歩進んだ画像ブロック
jun jun

【カスタムブロック】ページ内の画像を最適化!一歩進んだ画像ブロック

こんにちは!エンジニアの jun です。
非常にシンプルだけど、縁の下の力持ちになってくれるカスタムブロックをご紹介。
「設定するデメリットなし!」と言っても過言ではないので、ゼヒお試しを!

今回もすぐに試せるファイルをご用意しています。

カスタムブロックの読み込みについては、以下も合わせてご覧ください。

具体的には何をするのか

今回実現するのは、画像の遅延読み込み、そして非同期デコードへの対応です。

聞き慣れない言葉かもしれませんが、難しいことはありません。
<img> へ、属性を追加するだけです。
それぞれのビフォー/アフターを見てみましょう。

遅延読み込み

<img src="XXXXXXX">
↓
<img src="XXXXXXX" loading="lazy">

非同期デコード

<img src="XXXXXXX">
↓
<img src="XXXXXXX" decoding="async">

カスタムスクリプト

<img> へ属性を追加するのみなので、カスタムスクリプトも非常にシンプルです。
遅延読み込みの場合の例が以下。
5行目のMTBlockEditorSetCompiledHtml()については、少し専門的になるので、ここでは割愛させてください。いずれまた別の記事でご紹介したいと思います!

<script>
document.addEventListener('DOMContentLoaded', () => {
  if ( document.body.dataset.hasCompiledHtml ) return
  document.querySelector('img')?.setAttribute('loading', 'lazy')
  MTBlockEditorSetCompiledHtml(document.body.innerHTML.replace(/<!--\s+\/?mt-beb.*?-->/g, ""))
})
</script>

カスタムブロックとしては、これで以上です!
記事冒頭のファイルを読み込めば、お使いのサイトですぐに活用できると思います。

遅延読み込みとは

一足飛びにきてしまいましたが、用語の確認もしておきましょう。

まずは遅延読み込みと[loading="lazy"]について。

通常、ページ内の画像は全て一斉に読み込まれます。そしてそれは、ページにアクセスした最初のタイミングで開始されます。
遅延読み込みとは、そのタイミングを遅らせることです。

[loading="lazy"]が設定された画像は、最初は読み込みされません。
ページがスクロールされ、画像が表示エリアに近づくと読み込まれるのです。
必要な時に必要な分だけ読み込まれるので、非常に省エネで、ページ全体の速度改善に大きく寄与します。
嬉しいことに、これはブラウザの標準機能なのです。特別なプラグインなどは不要です。

特に効果が高いのが、画像を多く利用しているページです。
また、スマートフォンのように、一度に表示できる量が少ない環境でも力を発揮します。

非同期デコードとは

続けて非同期デコードと[decoding="async"]について。
こちらは「非同期」と「デコード」が組み合わさった用語ですが、それぞれ対になる言葉があるので、全てまとめてみていきましょう。

エンコード/デコード

エンコードの日本語訳は「符号化」。言うなれば「機械用に変換する」
デコードの日本語訳は「複合化」。言うなれば「人間用に変換する」

エンコード、デコードの解説画像

ウェブサイトが画像をエンコード/デコードする目的は、通信量の節約です。
エンコード/デコードは必須で、それ自体の有効/無効などは制御出来ません。
ただ、ブラウザがいつデコードするかは指定できます。それが次の同期/非同期です。

同期/非同期

同期は、言うなれば「上から順に処理する」
非同期は、言うなれば「上から順に処理しない。スキップして後回しにする」

同期、非同期の解説画像

通常、ページ内の画像は上から順にデコードされます。そしてそれは、ページにアクセスした最初のタイミングで開始されます。
さらに、「上から順に」というのは、画像だけでなくテキストなどのその他のコンテンツも含めた順番です。
非同期とは、この画像処理の順番をスキップして、後回しにすることです。

同期の場合、途中に画像があると、その処理が完了するまで次のコンテンツの処理へは進みません。ブロッキングと呼ばれる現象です。
一方、非同期の場合、画像処理はスキップして後ろへ回され、次のコンテンツの処理へ進みます。こちらはブロッキングが起こりません。

画像が大きくなるとデコードに時間がかかり、その間、ページ全体がブロックされてしまうわけです。
ページ全体を止めることなく、最適なタイミングで画像処理を行う。それが非同期デコードなのです。
こちらも当然、ブラウザの標準機能です。

遅延読み込みと非同期デコード、どちらを使う?

遅延読み込みも非同期デコードも、画像処理を効率よく行うための設定です。
それではどちらを使えば良いのでしょうか。

個人的には、以下のような方針を基本にしています。

  1. 全ての画像に [loading="lazy"] を指定する
  2. ただし、最初の一画面に表示される画像には [decoding="async"] のみ指定する

ページの先頭に大きく印象的な画像を置くことは多いと思います。
メインビジュアル、キービジュアル、ヒーロー、ジャンボトロンなどなど、文化によって呼び名はさまざまですが、そのような画像だけ非同期デコードを設定。それ以外は遅延読み込みを設定する方針です。
ご参考まで!

なお、両者を併記することも可能です(サンプルのカスタムブロックでは対応していません)。
ただ、その場合にどちらが優先されるかはブラウザによるようです。
2023年5月現在の Google Chrome では、遅延読み込みが優先されます。そういう意味でも「全て遅延読み込み!」というシンプルな方針でも良いと思います。

用語解説に多くを割いてしまいましたが、どちらもやることは非常にシンプルです。
そして、手間に反比例して効果は絶大です。
お勧めの設定なので、ゼヒ活用してください!