【高速化】 Defer.js を使って画像を高速に、確実に表示する方法
このサイトでは、画像の表示に外部のサーバーを利用しています。外部サーバーの利用は高速化に有効ですが、サーバーにトラブルが起こると画像が標示されなくなる問題があります。今回、速さを維持したまま信頼性を上げる方法を考えました。JetTheme が外部サーバーの画像をサムネイルとして認識しない問題にも対処します。

ポイント
- 外部の画像サーバーを使う時の問題を解決する
- 画像を後から差し替える
- hidden属性 と alt="Page thumbnail image" を使う
はじめに
画像をこっそり入れ替えたら、みんな気づくだろうか?
前回、Blogger の画像の表示を高速化するために、画像サーバーを変更したことを紹介した。
今回は、それによって生じる問題点に対処する。
画像が表示されなくなる可能性
このサイトでは、記事ページのトップ画像の表示に、前回紹介した ul.h3z.jp を利用している。
こちらのサーバーは高速なのでとても助かっているが、個人で運営されているので、いつかサービスが終了する可能性がある。
サービスが終了すると画像が標示されなくなってしまうので、使っている画像を1枚ずつ手作業で貼り直す必要がある。
これは大変なので、最悪の場合でも Blogger の画像サーバーから表示される状態にしておきたいと考えた。
Defer.js を利用する
書き手が使用している JetTheme には、Defer.js という遅延読み込み機能が組み込まれている。JetTheme はこれをふんだんに利用して、ページの表示を高速化している。
Defer.js は日本在住の Shin さんが開発したプログラムで、あトんさんが JetTheme 用のバージョンアップのコードも公開されている。
defer.js の サイト
GitHub - shinsenter/defer.js: 🥇 A lightweight JavaScript library that helps you lazy load (almost) anything. Defer.js is dependency-free, highly efficient, and optimized for Web Vitals.
🥇 A lightweight JavaScript library that helps you lazy load (almost) anything. Defer.js is dependency-free, highly efficient, and optimized for Web Vitals. - shinsenter/defer.js
after work lab あトんさんのサイト

最新のDefer.jsをJetThemeで使用する方法 - after work lab
はじめに Bloggerの無料テンプレートJetThemeはページスピードのパフォーマンスがトップクラスで使用しているユーザーも多数いらっしゃると思います。 ページスピードのパフォーマンスは高い理由は Defer.js を活用しているからです。 しかしJe...
Defer.js の使い方は、 アタル さんのサイトで詳しく解説されている。
gadgets-geek.net アタルさんのサイト

Defer.js 使い方 (利用方法) • ガジェおた(本館)
Defer.js@3.4.0〜利用方法。Defer.js はShinさんが作成したインラインでもわずか1.76KByteの「遅延ロード」JavaScriptライブラリの決定版。現在のWeb技術では遅延ロードとリソース(プリロード)ヒントの組み合わせが最も効果的と考え、Defer.all()で対応済み
今回の設定にあたって、これらのサイトを参考にした。上記の方々に重ねて感謝したい。
Defer.js の使い方
今回は Defer.js のシンプルな遅延読み込み機能を利用している。以下に、書き手の JetTheme での使用例を紹介する。
まずは、使用する画像を両方のサーバーにアップロードしておく。
次に、画像を挿入するとき次のように記述する。
<img class="defer-img" alt="画像の説明" src="元の画像のURL" data-src="差し替える画像のURL" height="高さ" width="幅"/>
最後に、テンプレートの最後の方にある /*Your Script is here to maintain performance.*/
の下に以下を記入する。
/*Your Script is here to maintain performance.*/
Defer.dom('.defer-img', 150);
数字の 150 は、150ミリ秒後に画像が切り替わるように設定している。パフォーマンスが低下しない範囲で、なるべく小さな値を指定する。
実際の動作
実際の差し替えを Chrome の 開発者ツール で確認してみる。

ページの読み込みに続いて、初期画像が読み込まれる。ul.h3z.jp は読み込みが早い。
ページの読み込み終了から 0.15 秒後に、blogger.googleusercontent.com の画像の読み込みが開始される。こちらは遅く、約1秒 かかっている。
そして、ページ読み込み開始から 約2秒後 に、画像が入れ替わっている。
Defer.js を使用したぶん少し読み込みは遅れているが、前回紹介した LCP が 約 1.8 秒 だったのでその差は大きくない。
Page Speed Insights の LCP は、約1秒 に短縮されている。
画像差し替えのメリット
この方法であれば、ul.h3z.jp がサービスを終了しても画像が表示される。
このページのトップ画像も、この方法で差し替えている。気になる方は キャッシュ を消去して再読込を試してもらいたい。
見た感じでは、画像の差し替えはほとんど分からないと思う。
さらに、実際は解像度の高いきれいな画像に差し替えている。
ユーザー体験を損なうことなく、画像の解像度を上げて表示できるので、書き手はこの方法に満足している。
画像差し替えのデメリット
デメリットは、画像を2回読み込むのでデータ通信量が増える。
これはについては、 初期画像を高圧縮にしておけば問題はないと考えている。
また、画像を挿入する時に少し手間が増える。
書き手はトップ画像のみ ul.h3z.jp を利用していて、Create Link という便利な Chrome の拡張機能も使っているので、実際はそれほど手間ではない。
高精細の画像の使用できることに、それを上回るメリットを感じるので、あまり負担は感じない。
この方法で、画像表示の信頼性について、それなりに良い解決ができたと思っている。
JetTheme がサムネイルを認識しない問題
※ 2024.6.15 追記
以前は <noscript>
を使用していましたが、レイアウトシフトが発生したため現在の方法に変更しています
後半は、サムネイル画像の問題について対処する。
JetTheme の場合、外部サーバーの画像をサムネイル画像として認識しない問題がある。
その場合、2番目の画像がサムネイル画像として表示される。
これに対して、トップ画像の前に サムネイル用の画像を挿入することで対応した。
実際の方法
サムネイル用の画像は、Blogger の画像サーバー https://blogger.googleusercontent.com/
に通常通りアップロードする。
サムネイル画像を挿入するときは、次のように記述する。
<img hidden alt="Page thumbnail image" loading="lazy" src="画像のURL" />
これで画像はサムネイルとして使われるが、実際のページでは非表示になる。
hidden属性
今回は <img>
に対して hidden
をつけることで、画像を非表示にしている。
hidden 属性は、見た目を非表示にする display:none; とは違って、html上で要素が非表示であることを示している。
alt="Page thumbnail image"
さらに、alt="Page thumbnail image" と記述することで、検索ボットに対してサムネイル専用の画像であることを伝えている。
全体として
hiddn 属性 は、適切に使えばペナルティを受けることは少ないとされている。
リスクは無いわけではないが、速度の面で外部のサーバーを使えるメリットは大きいので、書き手はこの方法を採用することにした。
まとめ
画像の表示に外部サーバーを利用したときの問題点と、その対策を紹介した。
画像の差し替えは、Defer.js を導入すれば誰でも手軽に利用できる。Defer.js は高速化だけでなく、いろいろ応用できるのでとても便利だと思う。
JetTheme は高速で良いテンプレートだが、挙動が難しいことも分かった。
次回は高速化についての最終回、 リソースヒント について考える。