概要
ウェブサイトの表示速度はSEOに大きな影響を与えます。その中でも今回はウェブページの要素の中で大きな容量を占める画像サイズにフォーカスします。
表示する領域に適切なサイズの画像でないと、小さすぎる場合はぼやけてしまい、大きすぎる場合は無駄に画像データを転送することになり表示に時間がかかります。
レスポンシブデザインやRetinaディスプレイ対応など高解像度のディスプレイに対応する場合一体どの種類の画像を用意するべきか悩ましい問題を検証・考察しました。
目次
- 概要
- 目次
- 目的
- 対象読者
- PR
- 本文
- 高解像度ディスプレイ(Retinaディスプレイ)とは
- PCのデバイスピクセル比調査
- PC
- モバイル
- HTMLでデバイスピクセル比をどの様に処理するか
- HTMLでデバイスピクセル比の違う端末でのレスポンシブ対応
- 考察
- Next.jsのImageライブラリはレスポンシブ画像やデバイスピクセル比に対応した画像を動的生成
- まとめ
- 著者
- 参考リンク
- PR
目的
ウェブサイトの表示速度はSEOに大きな影響を与えます。これはSpeed updateと呼ばれるアルゴリズムによって、ウェブページのリクエストから表示までのパフォーマンスが重要視されています。
参考: ページの読み込み速度をモバイル検索のランキング要素に使用します
またモバイルのトラフィックがインターネットのトラフィック全体の半分以上を占め、また表示が遅いと直帰率が上がります。これは関連する記事を見てもらいたいメディアや、商品を購入してもらいたいECサイトではウェブページの表示の遅さ見過ごすことはできません。
参考: Find out how you stack up to new industry benchmarks for mobile page speed
今回は、ウェブページの要素の中で大きな容量を占める画像サイズにフォーカスします。
ウェブページの表示領域に適切なサイズの画像でないと、小さすぎる場合はぼやけてしまい、大きすぎる場合は無駄に画像データを転送することになり表示に時間がかかってしまいます。
特にレスポンシブデザインや、Macに搭載されているRetinaディスプレイなどの高い解像度のディスプレイの場合、一体どの種類の画像を用意するべきか混乱しやすいため、どのサイズの画像を用意するべきか整理します。
対象読者
WebサイトやWebシステムのSEO・パフォーマンスに興味があるプロダクトオーナー、ソフトウェアエンジニア、FigmaやXDでデザインを行うデザイナ
PR
UZUMAKIではアジャイル開発で新規事業の開発から、大規模Webアプリケーションのアーキテクチャ更新などの開発をしています。
お問い合わせはUZUMAKIのHPのお問合せフォームから
本文
高解像度ディスプレイ(Retinaディスプレイ)とは
近年のiPhoneやmacに搭載されているディスプレイは、Retinaディスプレイといい、1インチあたりのピクセル(ドットの数)が通常のディスプレイのN倍となっています。1インチ四方の点の数が普通のディスプレイのN乗倍あります(iPhone 12 Proの場合は9倍)。
AndroidにもiPhoneの様に高解像度ディスプレイのものが当たり前のようにあり、ハイエンドなWindowsのPCもWindows10から高DPIスケーリングという機能でmacのRetinaディスプレイと同等の対応が必要です。
ちなみにこの位置インチあたりのドットの数をPPIやDPIといい、ディスプレイの解像度の文脈では場合は同じ意味です。
- DPIはdots per inch(1インチあたりのドットの数)
- PPIはpixels per inch(1インチあたりのピクセルの数)
PCのデバイスピクセル比調査
デバイスピクセル比とは、
デバイスピクセル比 = デバイス/CSS ピクセル比(または疑似解像度)
を表し、実際の画面のピクセル数と、ソフトウェア上で計算されるピクセル数の比を表します。
大雑把に実践的な言葉で表現するならば、デバイスピクセル比で掛けたサイズの画像を用意しないとぼやけてしまうということです。
PC
PCの場合は、実際の解像度とディスプレイの表示設定によって1ピクセルあたりの何ピクセル分の画像を表示するかが決まります。
macの設定画面を見るとデフォルト設定では、疑似解像度は 1792 x 1120 、実際の解像度は 3,072 x 1,920ピクセルとなっています(下記画像左下参照)。
Windowsも同様に、Windows10から高DPI対応というものがあり、Surfaceなどは高解像のディスプレイのものは推奨サイズが200%を推奨サイズとされています。
多くのユーザはこの解像度設定をデフォルトで使っていると仮定すると、下記の表の様に高解像度ディスプレイ向けに表示する領域の2倍の画像を用意する必要があります。
機種名 | デバイスピクセル比 | デバイスピクセル | デフォルト解像度 |
---|---|---|---|
Macbook pro 2019 16inch | 2 | 3,072 x 1,920 | 1,792 x 1,120 |
Surface Laptop 4 15 インチ | 2 | 1,248 x 832 | 2,496 x 1,664 |
モバイル
iPhoneやハイエンドなAndroidのデバイスピクセル比は2-4と、最低でも表示する領域の2倍の画像を用意する必要があります。
デバイスピクセル比が3倍や4倍の画像が小さいモバイルの画面上で本当になのかどうか、後述の比較のサンプルを各人の端末で確認してください。
機種名 | デバイスピクセル比 | デバイスピクセル(縦 x 横) | ポイント(CSSピクセル)(縦 x 横) |
---|---|---|---|
iPhone 12 Pro Max | 3 | 2,778 x 1,284 | 926 x 428 |
iPhone 12 Pro | 3 | 2,532 x 1,170 | 844 x 390 |
iPhone 12 mini | 3 | 2,340 x 1,080 | 780 x 360 |
iPhone SE | 2 | 1,334 x 750 | 667 x 375 |
iPhone 11 | 2 | 1,792 x 828 | 896 x 414 |
Google Pixel 4a | 3 | 2,280 x 1,080 | 760 x 360 |
Google Pixel 4XL | 4 | 3,040 x 1,440 | 760 x 360 |
その他iOSの端末のデバイスピクセルやポイント数はこちらのサイトがまとまっています。The Ultimate Guide To iPhone Resolutions
HTMLでデバイスピクセル比をどの様に処理するか
下記のURLで固定の画面幅で1〜3倍のサイズの画像を表示している。デバイスピクセル比の2以上の端末で動作を確認してみてください。
macのRetinaディスプレイの場合、1倍の画像だと若干ぼやけて見えます。これが文字を含んでいるとフォントが霞んで見えるのが顕著である。たまに文字が滲んだ画像のウェブサイトを見かける場合はこれが原因です。
この表示領域に対して適切なサイズの画像を表示する方法は、
<img>タグのsrcset属性と<picture>タグを使い複数の解像度の画像ソースを用意してブラウザに適切な画像を選択させる方法があります。今回は<image>タグのsrcset属性を使った例を使います。
具体的なsrcsetを使った<img>タグの例
<img id="srcSet"
srcset="https://source.unsplash.com/Jvw3pxgeiZw/225x400,
https://source.unsplash.com/Jvw3pxgeiZw/450x800 2x,
https://source.unsplash.com/Jvw3pxgeiZw/675x1200 3x,
https://source.unsplash.com/Jvw3pxgeiZw/900x1600 4x"
src="https://source.unsplash.com/Jvw3pxgeiZw/225x400"
width="225" height="400">
IE以外のブラウザはsrcset属性に対応している のでこの機能は実質的にどのブラウザでも機能しているいってよいでしょう。万一srcsetが対応していない場合もsrc属性で定義した画像を表示する仕組みなので問題ありません。
srcset属性の中で2x, 3x, 4xなどデバイスピクセル比に対応した画像を定義してあげるとブラウザが自動的に最適な画像をロードして画面に表示します。なのでsrcsetで用意した画像をブラウザが全部DLして余計なデータ通信を行いません。
このコードのサンプルも先程と同じリンク先の下の方にスクロールすると確認できます。
この<img>タグをデバイスピクセル比が3のiPhone 12 Proで確認すると3xの画像を使用していることを確認できます。
また2xまでの画像を用意して、3xを用意していない場合にデバイスピクセル比が3の端末で表示した場合は、ブラウザはsrcsetで定義されている中で一番解像の高い2xの画像を自動的に選択してくれるので安心です。
実際デバイスピクセル比が3のiPhone 12 proで2xの画像と3xの画像を見比べたときにそれほど差を感じなかったので、運用の手間を考えると2021年現在では2xの画像まで用意して置くだけでも良いかもしれません。
HTMLでデバイスピクセル比の違う端末でのレスポンシブ対応
画面幅いっぱいに表示したり囲まれた領域の幅のいっぱいに画像を表示する場合は、表示する対象のデバイスの横幅に最適な画像でないとぼやけたり、表示領域に大きすぎる画像をロードする事になってしまいます。
※レスポンシブサイトの場合、画面幅いっぱいに表示する画像や、下記のようにPCで表示する2列で表示するが、モバイルで表示すると1列で表示するような場合があります。
この問題に対応するためsrcset属性を1x 2xではなく、wを使ったウインドウサイズを使います。
ウインドウサイズはブラウザが実際に表示しているデバイスのピクセル数だと考えると理解しやすいです。デバイスピクセル比が2のデバイスの場合、見た目上320ピクセルの領域が表示されているので、使用さされる画像は320x2の640wがそれに当たります。
特にPCの場合は開いているブラウザの画面幅が予測できないので、適当なウインドウサイズの画像を用意してブラウザに自動的に最適な画像を選択させるようにします。
具体的なsrcsetを使った<img>タグの例
<img
id="responsiveImg"
src="https://source.unsplash.com/Jvw3pxgeiZw/225x400"
sizes="100vw"
srcset="https://source.unsplash.com/Jvw3pxgeiZw/640x1133 640w,
https://source.unsplash.com/Jvw3pxgeiZw/750x1328 750w,
https://source.unsplash.com/Jvw3pxgeiZw/828x1466 828w,
https://source.unsplash.com/Jvw3pxgeiZw/1080x1912 1080w,
https://source.unsplash.com/Jvw3pxgeiZw/1200x2124 1200w,
https://source.unsplash.com/Jvw3pxgeiZw/1920x3398 1920w,
https://source.unsplash.com/Jvw3pxgeiZw/2048x3625 2048w,
https://source.unsplash.com/Jvw3pxgeiZw/3840x6797 3840w"
>
上記<img>タグの例では
- 最小が640wであるので、デバイスピクセル比が2でCSSピクセルの横幅が375pxのiPhone SEの画面幅ギリギリの画像に適応しそうです
- 最大値の3840wであるので、デバイスピクセル比が2でCSSピクセルの横幅が1920pxの高解像度ディスプレイのPCに対応しそうです
- この640wから3840wの画像でそれぞれのデバイスが自動的に適切な画像を選択します
※ このどのwごとに画像を作るか(ブレークポイント)については後述するNext.jsの実装例を参考にしています
このコードのサンプルも先程と同じリンク先の下の方にスクロールすると確認できます
上記のサンプルを画面幅狭めでブラウザ開いて、Chrome dev toolsなどのデバッグツールのnetworkを開きながら画面幅をだんだん広くしていくと自動的に最適な横幅いっぱいの画像がロードされるのを確認できます。
この様にレスポンシブに真摯に対応しようとするとレスポンシブ向けに画像を沢山用意するのは面倒すぎる。cloudinary社が提供するレスポンシブサイト用の画像を自動生成してくれる下記のようなサービスを利用するが良いでしょう。
写真のような細かい画像ではなく、シンプルなイラストやアイコンではベクター形式のSVGを積極的に使うと多数の画像ファイルを用意する必要がなくて良いでしょう。
考察
表示する画像のサイズが同じでもデバイスピクセル比が違うディスプレイの場合は表示サイズの2倍(場合によっては3倍、4倍)の画像を必要とすることがわかりました。
またレスポンシブ対応において画面幅いっぱいの画像を適切なサイズを用意するためには、複数枚用意する必要がありかなり手間が発生してしまいます。
この問題を作業の手間を縮小化するため、フロントエンドのライブラリであるNext.jsを用いて実際に動作確認しました。Next.js(version 10以上)では動的に生成する手段が提供されています。
Next.jsのImageライブラリはレスポンシブ画像やデバイスピクセル比に対応した画像を動的生成
Next.jsではImageコンポーネントで<img>タグを、srcset属性を用いたHTMLを生成することができ、その対象の画像についても動的に生成する事ができます。
さらに動的に画像を生成する際に画像の圧縮率高いWebP対応のブラウザからのリクエストでは、WebP形式の画像を生成して返します。また同じリクエストが来た際にもキャッシュを利用して画像生成のコストを下げる機能もあります。
固定サイズの画像のNext.jsのコード
import Image from 'next/image';
<Image src={"/images/profile.jpg"} width={200} height={200} layout="intrinsic"/>
生成されるHTML srcsetに1x, 2xの画像が用意されている
<img
src="/_next/image?url=%2Fimages%2Fprofile.jpg&w=640&q=75"
decoding="async"
style="position:absolute;top:0;left:0;bottom:0;right:0;box-sizing:border-box;padding:0;border:none;margin:auto;display:block;width:0;height:0;min-width:100%;max-width:100%;min-height:100%;max-height:100%"
srcset="/_next/image?url=%2Fimages%2Fprofile.jpg&w=256&q=75 1x,
/_next/image?url=%2Fimages%2Fprofile.jpg&w=640&q=75 2x"
>
レスポンシブにする画像のNext.jsのコード
import Image from 'next/image';
<Image src={"/images/img.jpg"} width={600} height={400} layout='responsive'/>
生成されるHTML デバイスサイズごとにsrcsetに画像が用意されています
<img
src="/_next/image?url=%2Fimages%2Fimg.jpg&w=3840&q=75"
decoding="async"
style="position:absolute;top:0;left:0;bottom:0;right:0;box-sizing:border-box;padding:0;border:none;margin:auto;display:block;width:0;height:0;min-width:100%;max-width:100%;min-height:100%;max-height:100%"
sizes="100vw"
srcset="/_next/image?url=%2Fimages%2Fimg.jpg&w=640&q=75 640w,
/_next/image?url=%2Fimages%2Fimg.jpg&w=750&q=75 750w,
/_next/image?url=%2Fimages%2Fimg.jpg&w=828&q=75 828w,
/_next/image?url=%2Fimages%2Fimg.jpg&w=1080&q=75 1080w,
/_next/image?url=%2Fimages%2Fimg.jpg&w=1200&q=75 1200w,
/_next/image?url=%2Fimages%2Fimg.jpg&w=1920&q=75 1920w,
/_next/image?url=%2Fimages%2Fimg.jpg&w=2048&q=75 2048w,
/_next/image?url=%2Fimages%2Fimg.jpg&w=3840&q=75 3840w"
>
srcset中の640から3840wという区切りは、Next.jsのデフォルトの設定に則っています。設定ファイルで変更はできますが、設計者が考え抜いて設定されていると思われるので強いこだわりがなければデフォルトの設定で良いでしょう。参考: Basic Features: Image Optimization
※ ただし万能に見えるNext.jsのImageコンポーネントですが、現在のところコンパイル時に静的に画像を生成しておくことはできません。使うためにはCloudinaryを始めURLで画像を生成するサービスを利用する必要があります。ただしNext.jsを開発している最近流行りのVercelにデプロイする場合は細かい設定が不要です。
参考: Basic Features: Image Optimization
Next.jsを利用したサンプルコード
まとめ
ウェブサイトの表示速度はSEOや直帰率に大きな影響を与えます。今回は表示速度に大きな影響を画像にフォーカスしました。macやiPhone以外にもハイエンドなAndroidやWindowsも高解像度の画像が必要でした。また実際の画面を構成するピクセル数とソフトウェア的なピクセル数の比の概念は、デバイスピクセル比を用いて表すことがわかりました。
レスポンシブデザインに必要な画像を用意するべきか洗い出しました。また静的に用意するのは手間がかかるので、Next.jsを用いてレスポンシブデザインに対応する画像を動的に生成するサンプルも提案しました。
著者
名前: 今 佑介
Twitter 🐦 : @kon_yu
Github 🐙: https://github.com/konyu
参考リンク
- SEOにおける画像の最適化のまとめ【2019年度最新版】
- Lighthouseの計測結果を見ていく
- Performance audits
- 〜UIデザイナーのための各端末サイズ比較〜解像度/アスペクト比/Retina(高精細液晶)サイズ早見表|Nviveto|note
- 画像|Google Developers
- レスポンシブ画像 - ウェブ開発を学ぶ \| MDN
- 面倒なレスポンシブイメージの画像作成を自動化してくれる神ツールとブレイクポイントの考え方 \| Rriver
- imgのsrcset属性について - Qiita
- Next.js 10のnext/imageによる画像最適化を試してみた
PR
XではUZUMAKIの新しい働き方や日常の様子を紹介!ぜひフォローをお願いします!
noteではUZUMAKIのメンバー・クライアントインタビュー、福利厚生を紹介!
UZUMAKIではRailsエンジニアを絶賛募集中です。
↓の記事を読んでご興味を持っていただいた方は、ぜひ応募よろしくお願いします!
是非応募宜しくおねがいします!