Open6

サイトの画像サイズどうするか考える

きのこのこきのこのこ

最近の出し分け書き方

DPR は10とかまであるらしい。

見えにはこだわっているだろう Apple のサイト
https://www.apple.com/jp/iphone-14-pro/
1x, 2x 画像を用意しつつ、4段階のメディアクエリに対応。

<picture id="key-features-hero-hero-1" class="key-features-hero-hero hardware-static loaded" aria-hidden="true" data-picture-loaded="">
    <source srcset="/jp/iphone-14-pro/images/key-features/hero/hero__cj6i78tzkp8i_small.jpg, /jp/iphone-14-pro/images/key-features/hero/hero__cj6i78tzkp8i_small_2x.jpg 2x" media="(max-width:734px)">
    <source srcset="/jp/iphone-14-pro/images/key-features/hero/hero__cj6i78tzkp8i_medium.jpg, /jp/iphone-14-pro/images/key-features/hero/hero__cj6i78tzkp8i_medium_2x.jpg 2x" media="(max-width:1068px)">
    <source srcset="/jp/iphone-14-pro/images/key-features/hero/hero__cj6i78tzkp8i_large.jpg, /jp/iphone-14-pro/images/key-features/hero/hero__cj6i78tzkp8i_large_2x.jpg 2x" media="(min-width:0px)">
    <img src="/jp/iphone-14-pro/images/key-features/hero/hero__cj6i78tzkp8i_large.jpg" onload="__lp(event)" alt="">
</picture>

Google さんは JS で何サイズか切り替えているよう。
https://store.google.com/jp/product/pixel_7?hl=ja

<degu-image degu-asset="" src="https://lh3.googleusercontent.com/PzZ6QQ1_moxwn-IDN3AEI4G5b8eetyZkBPdd5MFu_fFSirhPUOfHkufcSpfPdibZYa_lySNwR5VdrvIgyEr9ANwygYNyz714Nm0" width="1368" height="1140" style="aspect-ratio: 1368 / 1140" alt="水滴のついた Google Pixel 7 の背面" class=" mqn-opt--laptop-gt-only mqn-opt--rounded-corners" no-width="true"><!---->
    <img loading="eager" width="1368" height="1140" src="https://lh3.googleusercontent.com/PzZ6QQ1_moxwn-IDN3AEI4G5b8eetyZkBPdd5MFu_fFSirhPUOfHkufcSpfPdibZYa_lySNwR5VdrvIgyEr9ANwygYNyz714Nm0=rw-e365-w1400" alt="水滴のついた Google Pixel 7 の背面" data-iml="153005.5">
</degu-image>

画像の描画サイズで切り替える方法。実際の利用サイトが見つからない。
その画像が必要と思われるサイズが自動で使われる。

<img src="img/original.png"
  srcset="img/828w.png 828w,
  img/1242w.png 1242w,
  img/original.png"
>
きのこのこきのこのこ

使い分け

画像の表示サイズが固定なレイアウトなら、DPR 指定で事足りる。

横幅いっぱいの画像など、画面幅によって画像の表示サイズも変わるなら、画像サイズで分けた方が良い。
メディアクエリによってカラム構成が変わるなど、レイアウトに変更がある場合は、必要な画像の大きさが変わるのでメディアクエリ+何かでの出し分けになる。
ブラウザ対応は w による指定も安心して使える範囲。

w で指定する場合、カラムレイアウトによる画像サイズの概算を sizes で伝える。
レイアウトの情報が CSS と HTML に散る。
DPR 指定の方が、サイズ指定は CSS に集約されるので分かりやすいかも。

きのこのこきのこのこ

画像のサイズはどんなバリエーションで用意するか

サイト訪問者の画面サイズ

GA で画面の解像度を見る。
そもそも GA で出る解像度ってデバイスピクセル?CSS ピクセル?
モデル名と画面解像度でレポートを作る。

Pixel 6a は CSS ピクセル:432x960、デバイスピクセル:1080x2400

ブラウザのウィンドウサイズ(CSSピクセル)で出ているようなので、画像サイズを考えるのには役に立たなかった。

他のプラットフォームでは

Next.js

<img
  alt="xxxxxx"
  sizes="100vw"
  srcset="
    /_next/image?url=%2Fsample.jpg&amp;w=640&amp;q=75   640w,
    /_next/image?url=%2Fsample.jpg&amp;w=750&amp;q=75   750w,
    /_next/image?url=%2Fsample.jpg&amp;w=828&amp;q=75   828w,
    /_next/image?url=%2Fsample.jpg&amp;w=1080&amp;q=75 1080w,
    /_next/image?url=%2Fsample.jpg&amp;w=1200&amp;q=75 1200w,
    /_next/image?url=%2Fsample.jpg&amp;w=1920&amp;q=75 1920w,
    /_next/image?url=%2Fsample.jpg&amp;w=2048&amp;q=75 2048w,
    /_next/image?url=%2Fsample.jpg&amp;w=3840&amp;q=75 3840w
  "
  src="/_next/image?url=%2Fsample.jpg&amp;w=3840&amp;q=75"
  width="1980"
  height="1150"
  decoding="async"
  data-nimg="1"
  loading="lazy"
  style="color: transparent; height: auto; width: 100%;"
/>

下の方は大体 iPhone の画面サイズと合っている。

どうするか

自サイトのブレイクポイント:900px
PCレイアウトでは横幅 1240px 固定

sizes でメディアクエリごとのサイズ感を指定。
画像は何種類か代表サイズ決めて書き出し(スマホデザインでのサイズ、PCデザインでのサイズ、さらに2倍サイズ?)

幅いっぱいの画像なら
640w:Next.js 最小。320px の 2x
750w:iPhone SE(第2世代)、iPhone 6, iPhone 7 あたり。GA で見たときに 375w は多い。
900w:独自、SPレイアウトで横幅いっぱいの大きいサイズ(1080 でも良いか?)
1200w:PCレイアウト横幅いっぱい
1800w:SP 900w 2x(1920 でも良いか?)
2048w:PCレイアウト、2x サイズ

SP 横幅いっぱい、PC 2カラム
640w, 750w, 900w, 1800w:SP
600w, 1200w:PC → 600w は 640w と統合
640w
750w
900w or 1080w
1200w
1800w ow 1920w

SP横幅いっぱい、PC3カラム
640w, 750w, 900w, 1800w:SP
400w, 800w:PC → SPサイズで良さそう
640w
750w
900w or 1080w
1800w or 1920w

きのこのこきのこのこ

画像書き出しを楽にする

Figma で Export の + からバリエーションを追加。

ただしこれ、どれかの画像を選択して設定しても、他の画像を選択した状態だと設定が引き継がれない。
画像ごとに設定するのは面倒すぎる。エクスポートの設定って保存しておけたりしないの?

プラグインでできた。
https://www.figma.com/community/plugin/933557553455124671/Export-Presets

きのこのこきのこのこ

ついでに WebP

ウェッピーと読むらしい。
もう結構な割合のブラウザが WebP 対応しているので、丁寧な画像サイズの出し分けは WebP で行い、フォールバックとして1ファイル png を用意しておくだけにする。

こんな感じになるはず。

<picture>
    <source type="image/webp"
        sizes=" (min-width: 900px) XXXpx,
                100vw"
        srcset="
          img/image-640.webp 640w,
          img/image-750.webp 750w,
          img/image-1080.webp 1080w,
          img/image-1200.webp 1200w,
          img/image-1920.webp 1920w,
        "
        >
    // fallback on original src.
    <img 
        src="img/image-orig.png" 

        alt="image description">
</picture>

WebP へは squoosh で画像変換する。
→1枚ずつしか変換できないので https://saruwakakun.com/tools/png-jpeg-to-webp/ の方が良さそう。

きのこのこきのこのこ

変換手作業は面倒なので、複数サイズ画像の作成と合わせてコマンド化する。