プロも知らない?Webページの画像読み込みテクニック



プロも知らない?Webページの画像読み込みテクニック

2020年 3月、とある Web サイトがリニューアルされたとのことでアクセスしてみると、、、なかなか読み込まれません。

モバイルファースト時代にとって、ページの読み込み時間って重要ですよね。 今回は、HTML や CSS の教科書には載っていない画像の最適化テクニックについてご紹介させていただきます。

目次
  1. プロも知らない?Webページの画像読み込みテクニック
  2. SEOと画像サイズ
  3. WordPressでも採用されている「srcset」
  4. 画像を遅らせて読み込ませる「IntersectionObserver API」
  5. ボタンや背景はCSSで
  6. まとめ

プロも知らない?Webページの画像読み込みテクニック

SEOと画像サイズ

画像の読み込みテクニックをご紹介させていただく前に、まずは SEO についておさらい。

  • ページの読み込み時間が 3秒を超えると半分のユーザーが離脱
  • Google はページの読み込みスピードを重視
  • 日本の平均通信速度(29Mbps)で読み込めるページサイズは 4MB/秒

今回の記事のきっかけになった Web サイト、デザインはモダンでお洒落ですが、 Google のスピードテストにかけてみると 「3点」。

image

PageSpeed Insights

"3点" の理由を確認すると、CSS コードなどが不適切なことに加えて、画像サイズが大きいとのこと。次世代型の画像フォーマット .webp にすれば大幅にサイズを圧縮できると紹介されていますが、 .webp は Safari で対応していないため ❌ ですよね。

今回はその他の方法で、画像を適切に読み込む処理をご紹介させていただきます。

WordPressでも採用されている「srcset」

2005年ぐらいから各ブラウザが対応を始めた img タグに関連する srcset 属性。コードの例としては以下の通り。

<img src="https://pythonchannel.com/static/images/codecamp/img/srcset/L.jpg" srcset="https://pythonchannel.com/static/images/codecamp/img/srcset/L.jpg 1500w, https://pythonchannel.com/static/images/codecamp/img/srcset/S.jpg 357w, https://pythonchannel.com/static/images/codecamp/img/srcset/M.jpg 900w" sizes="(max-width: 1000px) 100vw, 1000px">

ちょっと長いですが、これで一箇所の画像を読み込む HTML コードです。

従来は画像読み込みタグ <img> の中は、 src="" だけですが、 srcset="" を加えると画面サイズに合わせて適切な画像を自動的に選択してくれます。実際に srcset を使ってサンプルコードを書いてみました。 CodePen のページに行くか、コードをコピペして画面幅を変えて、読み込み画像が変わるか確かめてみて下さい。

従来はこうした画面幅による画像の切替、 CSS の @media で組んでいた方も多いと思いますが、 srcset を使うと @media がなくても画像を自動で切り替えできます。

上記コードは WordPress 流の書き方で、 W3School などは以下の様な書き方を紹介しています。

<picture>
  <source media="(min-width: 1200px)" srcset="img/big/lion.jpg">
  <source media="(min-width: 900px)" srcset="img/m/lion-768x576.jpg">
  <img src="img/small/lion-300x225.jpg">
</picture>

どちらでも結果的には同じですが、前者の WordPress スタイルの方は画面幅と画像サイズの近似値を計算し、 "1" に近い画像を読み込みます。そのため用意する画像サイズと srcset でセットするサイズ幅を適切に保たないと、小サイズを読み込んで欲しいのに "中サイズ" を読み込むということも。特に画面サイズより小さい画像サイズの場合は、ワンランク上の画像サイズが自動的に読み込まれるので要注意。 こうしたことから srcset は、 <picture><source> を組み合わせる方が制御しやすいかもしれません。

【srcsetの読み込み画像の計算式】
小画像の幅 357px
中画像の幅 900px
大画像の幅 1500px

iPhone SE 画面幅 320px の場合
357 ÷ 320 = 1.115
900 ÷ 320 = 2.812

1 に近いのは 357 サイズの画像なので、小画像 が読み込まれる。

srcset、便利そうな HTML の属性ですが、画面幅毎に画像を用意しないといけないという点がデメリット。 WordPress の様にアップロードした画像を自動でリサイズしてくれる場合は ○ ですが、そうでない場合は画像作成時に数種類用意する、もしくは WordPress の様にリサイズのスクリプトを組み込むという手間がかかります。

次はこうした画像生成の手間をかけたくない時の解決策をご紹介。

画像を遅らせて読み込ませる「IntersectionObserver API」

image

IntersectionObserver、ちょっと長い英語ですが、意味は「要素間交差を監視する」というこれまた難しい内容。こちらのメリットとしては、画面スクロールした時に初めて画像データを読み込む様にセットできるもので、最初のページロード・タイムを削減できるメリットがあります。ワンページなどページが長いデザインの場合に有効となってくるでしょう。

読み込み遅延以外にも、一定の位置までスクロールされたら自動で動画を再生するなど様々な JavaScirpt 制御を行えます。

また従来こうした画像読み込みの遅延というと JavaScript のスクロールイベントが使われていましたが、端末毎にイベントの位置が変わったりして使いにくい面もあったり、スマホではスクロールつまりを起こすことも。こうした問題を IntersectionObserver API が解決してくれるというわけですね。

早速 IntersectionObserver API を使った場合と使っていない・・・・・・場合を確認してみましょう。

こちらは 25枚の画像を組み込んだ HTML ファイルで、画面スクロールで下から 300px いったところで画像を読み込む様にセットした内容。 下にスクロールしていくとライオンの画像が他の動物の画像に切り替わっていき、IntersectionObserver API によって最初の読み込み画像を制御できている様子が確認できます。

次に IntersectionObserver API を使っていないパターンをご紹介。

一見すると先ほどの IntersectionObserver API を使ったパターンと変わらない様にも見えますが、Google 的には全く異なる評価を下しています。

image

IntersectionObserver API あり(リンク) IntersectionObserver API なし(リンク

どちらも同じ 25 枚の画像を読み込む仕様にもかかわらず、適切な読み込み処理をするかどうかで 30点以上も開きが。これは SEO 的に違いが出てきそうですよね。 66点の方を詳しく見ていきますと、下図の様に画像処理に関するアドバイスがあり、画像サイズの他に "オフスクリーン画像の遅延読み込み" が提案されています。

image

今回の IntersectionObserver API は、この 「オフスクリーン画像の遅延読み込み」 の改善に当たりますので、 Webデザインや Webディレクターを目指す人としては知っておきたい項目と言えるでしょう。

実際の IntersectionObserver API を使うプログラムは JavaScript によって制御されていて、やや難易度は高めです。まず MDN の IntersectionObserver API のドキュメント(リンク)は 18,000文字近くある長文で、内容をサクッと理解する事は困難。さらにサンプルプログラムを見ても、書き方は色々で、コードも長め。

そんな中一番分かりやすかったのが CSS Trick で紹介されているプログラムで、それを元に作成したプログラムが上記 に。 300 の値を変更してみたり、 img タグを他のものに変更したりして、遅延読み込みを体験してみてください。

尚、この IntersectionObserver API 、今回の様なシンプルな <img> タグであれば簡単ですが、 <div> 内のタグや要素の取り扱いになると複雑です。 JavaScript の基礎があっても複雑な制御文になりますので、どこまでの処理が実行できるか一度ご自身で体験してから実務に使用することを薦めますね。

例えば、 Google API による iframe を多数読み込むページ(https://pythonchannel.com/myapp/youtuber/)。こちら div の id から iframe を読み込んでいるのですが、項目が 30 以上あり、読み込みに時間がかかります。この遅延問題を IntersectionObserver API で解決しようと 1時間ほど試みましたが、結果は ❌。 改めて自分の JavaScript のスキル不足を実感する限りです。

画像の遅延読み込みについては、現在のことろ IntersectionObserver API より JQuery の Lazy の方がメジャーかもしれません。ただスマホデザインの場合は、別途 moile.lazyloader.js を読み込まないとイケナイなど、やや煩雑な作業が伴いますので、 IntersectionObserver API の様なワンランク上のプログラムを使える様に、 JavaScript マスターしておきたいですね。

ボタンや背景はCSSで

HTML5 と CSS3 の時代になって表現の幅が広がり、ほとんどのケースで "ボタン" は CSS でデザインさてる様になってきました。元々ボタンは画像サイズが小さいので、ページサイズや読み込み時間に与える影響は少ないですが、改めて同じボタンを画像とCSSで読み込む場合で比べてみました。

はい、やはり CSS でボタンをデザインした方がページサイズは小さく、画像仕様のボタンページに比べて、CSS 仕様のボタンページは 1.4kB と極小です。

ページ全体のデザインにもよると思いますが、 CSS でボタンを組む方が、大きさや色合い、文字などを編集しやすく、画像ボタンに比べてメンテナンス性、生産性は上でしょう。つまり改めてボタンは CSS で OK ということが確認できましたね。

Webサイト制作スキルが身に付く

CodeCampの無料体験はこちら

まとめ

今回ご紹介した srcset や IntersectionObserver API をはじめ、今後本格化するかもしれない Portal という新しい機能など、それらの多くは "スマホ" をターゲットにした仕様。 今後はウェブデザインといえば、まずはスマホデザインが優先表示でパソコンはその次、となるでしょうね。

こうしたスマホでも快適に、高い生産性で開発できる様に作られていく新しい機能には、 JavaScript や CSS の基礎は欠かせません。

「JavaScript、何回読んでもパッとしないんだよな...」「CSSはなんとなく分かっているけれど、スマホデザインになると...」 と、頑張ってはいるもののイマイチ自信が持てない方、 CodeCamp で現役エンジニアから指導を受けてみませんか?

今までモヤモヤしていたことが、パッと晴れるかもしれませんよ。「そういえば今夜ちょっと時間あるな」 という方は、まずは無料体験や LINE 相談から初めて、自分の理想とする未来に挑戦してみませんか?

オシママサラ
この記事を書いた人
オシママサラ
\ 無料体験開催中!/自分のペースで確実に習得!
オンライン・プログラミングレッスンNo.1のCodeCamp