レイアウトシフト回避したいついでにレスポンシブ画像とかいろいろな画像の読み込み方を整頓しとく

やりたいこと

画像の表示ってとても必要だけど、快適にサイトを見るには作るの結構気を使うんですよね~。あまり気を使えてないから、ちょっと今一度メモメモしといて、気を使えるようになろうかな~。

レイアウトシフト回避

読込が遅れてるコンテンツが表示されることで、今まで見てたコンテンツが急にガクンと場所が変わる現象、レイアウトシフト。
利用者視点で見ると結構イラっとするんですよね。
ページ読み込みきる前に目的のもの見つけてタップしようとした瞬間にズレっとかね。 でも、画像を全部読み込み終わるまでなにの描画もしないなんてね…
それも困るから、どうしといたらいいのかメモメモ。

HTMLにwidth/height属性を追加

<img src="hoge.jpg" width="300" height="124">

従来はwidth/height属性はピクセルの数値指定だったけど、現在は数値に単位を指定しないことで比率計算的(アスペクト比指定)に使えるらしい。
cssで↓的な指定をすれば、先祖要素をもとにレスポンシブ対応もできるよ。よきよき。

img {  width: 100%;  height: auto;}

CSSでaspect-ratioを設定する

CSSでaspect-ratioを設定しておくと、CSSのレイアウト指定の計算でプレースホルダーの領域をあらかじめ指定しておけるそうな。
IEがサヨナラした現在は普通に使えるし、便利!ありがたい!

img {  width: 100%;  aspect-ratio: 16 / 9;}

パフォーマンス改善

ブラウザのリソース読込みに対して指定をすることで、ブラウザのローディングスレッドとコンテンツの表示のバランスをいい感じにして、早くユーザーさんにいい感じにコンテンツを届けましょ、っていう対応、それがパフォーマンス改善。

Lazy Loading

Lazy Loadingとは、視覚的ビューポート(現在表示されているところ)以外の読込を遅らせるということ。
読込遅延を発生させることで、文章の読込を最適化させることができる。

ひと昔まえまでは、遅延によってSEOの影響があるだとか、ブラウザによる対応がマチマチすぎるマチマチ感があった…気がするのだけど、今は単純明解。

読込が発生しない分、レイアウトシフトもおきるので、回避する設定を一緒に行うことを忘れずに。

<img src="hoge.jpg" width="300" height="124" loading="lazy">

loadingが取る値は↓

説明
eager既定値すぐに画像読込開始
lazyブラウザがこの画像が必要と判断するまで待て

読込み処理の指定(Decode)

とりあえず、書き方。

<img src="hoge.jpg" decoding="async">

decodingが取る値は↓。意訳してるので違う場合は教えてください…

説明
sync他のコンテンツと同期的に読込みしてね
async他のコンテンツと非同期的に読込みしてね
auto既定値ブラウザにお任せ

syncすると、他のコンテンツがこの画像を読み込むのを待ちます=表示が遅れるかもしれないな~

asyncすると、この画像のことは置いといて、読み込む=この画像は後から追っかけ表示になるかもな~

レスポンシブ画像

レスポンシブでサイトがつくられるのも当たり前になってるけど、表示されるスクリーンサイズは様々で。さらに言うと、みため小さいのに、高解像度なデバイスもあったり。

ムダに大きい画像を読み込むのも負担だし、スクリーンの画角によっては表示させたい画像範囲が違ったり。

えぇい!ややこしい!

に立ち向かいつつ、いい感じの画像を表示しようよ、っていうのがレスポンシブ画像。

ひとつのimgタグで読込わけるsrcsetsizes属性

  • 画像のパスとサイズ
  • 表示の条件

を指定することで、HTML上で条件をよみとって表示を切り替えることができる

HTMLの書き方は↓

<img  srcset="hoge-small.jpg 320w,          hoge-medium.jpg 480w,          hoge-large.jpg 800w"  sizes="(max-width: 320px) 280px,          (max-width: 480px) 440px,          800px"  src="hoge-large.jpg">

src属性は<img>タグの必須要素なので、記載を忘れずに。候補画像のひとつとしても扱われるみたい。

この方法は、同じ画像のサイズ違いを表示させるというのが前提の方法。スクリーンサイズによって全然別のコンテンツを表示させたい場合には適さないので気をつけて!

画像のパスとサイズを指定する - srcset

srcsetに【 画像のパス+半角スペース+画像の横幅実寸ピクセルサイズ(単位:w)】をカンマ区切りで列挙。

srcset="hoge-small.jpg 320w,        hoge-medium.jpg 480w,        hoge-large.jpg 800w"
表示の条件を指定する - sizes

sizesに【メディアクエリ+空白+条件成立時のソースサイズ(幅)】をリスト化。
条件にあてはまらないときのデフォルトサイズとして、最後にメディアクエリ無しのものも記載しておきましょう。

sizes= "(max-width: 320px) 280px,        (max-width: 480px) 440px,        800px"

↑の例だと、

  1. 画面幅320px以下の時は280px位の横幅の画像
  2. 画面幅480px以下の時は440px位の横幅の画像
  3. そうじゃないときは800px位の横幅の画像 を、srcsetの画像から選ぶよ

な感じ。

表示サイズは同じ。解像度だけでファイルを変えたい

srcsetは横幅(単位:w)ではなく、画面解像度(単位:x)でも指定可能。 ↓にしておくと、解像度によって表示画像を切り替えてくれるそうな~

<img  srcset="hoge-low.jpg,          hoge-middle.jpg 1.5x,          hoge-high.jpg 2x"  src="hoge-high.jpg">

そもそもがっつり素材を変更できる<picture>

とりあえず、HTMLの書き方から。

<picture>  <source media="(max-width: 680px)" srcset="hoge-a.jpg">  <source media="(max-width: 960px)" srcset="hoge-b.jpg">  <img src="hoge-b.jpg" alt="hogeはhogeだよ"></picture>

<picture>の中身は<source>を0個以上、<img>を1つ。

<source>でリストアップされている中からブラウザが条件に合うものを選択。適切なものがなかったら<img>を使う。

<source>に設定する値はこちら↓

プロパティ説明
media表示の条件。メディアクエリを記載
srcset前述の<img>での説明と同じ。
sizessrcsetとセットで使うやつ。前述と一緒
typeMIMEタイプの宣言。宣言しておくと、その形式の対応ブラウザかどうかも指定できる

前述の例にsrcsetをリストアップすることで、さらにいろいろよしなにブラウザに選んでもらえるようになるようで。

 <picture>  <source media="(max-width: 680px)" srcset="hoge-small.png 720w, hoge-medium.png 1280w, hoge-large.png 1920w"/>  <source media="(max-width: 960px)" srcset="fuga-small.png 720w, fuga-medium.png 1280w, fuga-large.png 1920w" />  <img src="hoge.png" /></picture>

<img srcset><picture>

<img srcset>はそもそも、同じ画像をサイズや解像度違いで準備していることを前提としているため、ブラウザによっては、先に大きい画像を読み込んでいるとウィンドウを小さい画像対応のものにリサイズしても、改めて読込直したり直さなかったりする…っぽい。
に対して、<picture>はクライアントサイドの状態によって別のものを読み込むんじゃ~なタグ。

読み込むコンテンツの必要性によって使い分けれるといいね。

ファイルの圧縮と形式

最近使う系だと、この辺りでしょうか

形式(拡張子)説明
jpg写真系の画像で使う非可逆圧縮な形式。適切に圧縮して使おうね
pngイラストとかで使うことが多い形式。透過部分がある画像にも使えるよ
svgベクター形式が使える=1ファイルでいろいろなサイズを画像の荒れなく表示できる形式
webpjpgやpngより高い圧縮率で使える、今からいい感じな形式

これらのファイル形式を運用方式や制作制限等々にあわせて準備できるとよいですね~。

ちなみに、下記のようにtype指定して書くと、

  1. svgが使えるブラウザにはsvg
  2. webpが使えるブラウザにはwebp
  3. どちらも使えなかったらpng

のファイルが表示されるようにできるとよ。

<picture>  <source type="image/svg+xml" srcset="hoge.svg">  <source type="image/webp" srcset="hoge.webp">  <img src="hoge.png" alt="hogeなhoge画像"></picture>

おわり

は~。ちょっとレイアウトシフトのこと書こうとしただけだったのに、いろいろ周辺情報付けたしたら長くなった…