コーポレートサイトの SEO チェックをしたところ、PageSpeed Insights で「画像配信を改善する」という指摘が多く出ました。原因を調べると、表示幅が 300px ほどの写真に 3000×2000px の元画像がそのまま使われていたり、ニュース記事に 3000px の写真がフルサイズで挿入されていたりしました。
クライアントが自分で記事を書くサイトでは、どんな大きさの画像がアップロードされても、表示する幅に合ったサイズで表示される仕組みが必要です。この記事では、WordPress のテーマ側で行っている画像管理の設定をまとめます。
アップロードした画像の縮小・圧縮・WebP 変換は、プラグイン「EWWW Image Optimizer」で行っています。プラグインの設定は「EWWW Image Optimizerの設定|無料版で画像を自動圧縮・WebP化する手順」にまとめました。
EWWW Image Optimizerの設定|無料版で画像を自動圧縮・WebP化する手順 | CODE-PLUS(コードプラス) WordPressの画像最適化プラグイン「EWWW Image Optimizer」を無料版で使うときの設定を、タブごとに画面つきで解説します。最大画像サイズ2560px、ピクセルパーフェクト圧縮、WebP変換とリライトルールの設定、有料の「簡単I... 続きを読む全体の流れ
画像は、次の3段階で管理しています。
| 段階 | 担当 | 内容 |
|---|---|---|
| アップロード時 | EWWW Image Optimizer | 長い辺を 2560px までに縮小し、圧縮と WebP の作成を行う |
| サイズの生成 | テーマ(functions.php) |
本文用(1200px)と一覧用(768px)などの縮小版を作る |
| 挿入・表示 | テーマ(functions.php)と WordPress 本体 |
本文には「大(1200px)」で挿入し、srcset で画面に合ったサイズを表示する |
画像サイズの登録
WordPress は、画像をアップロードするたびに、登録されているサイズの縮小版を作ります。初期状態では、使わないサイズまで作られるので、テーマ側で整理しています。
//アイキャッチの有効化
add_theme_support('post-thumbnails');
//アイキャッチ・サムネイル画像サイズの設定
function mythumbnails_setup() {
//アイキャッチサイズを作成しない
add_image_size('medium', 0, 0);
add_image_size('1536x1536', 0, 0);
add_image_size('2048x2048', 0, 0);
add_image_size('et-pb-post-main-image', 0, 0);
add_image_size('et-pb-post-main-image-fullwidth', 0, 0);
add_image_size('et-pb-portfolio-image', 0, 0);
add_image_size('et-pb-portfolio-module-image', 0, 0);
add_image_size('et-pb-portfolio-image-single', 0, 0);
add_image_size('et-pb-gallery-module-image-portrait', 0, 0);
//アイキャッチサイズを追加する
add_image_size('thumbnail', 300, 300, true); //管理画面メディア一覧用, true = 切り抜く
add_image_size('medium_large', 768, 0); //一覧用, 0 = 高さ無制限
add_image_size('large', 1200, 0); //本文用, 0 = 高さ無制限
}
add_action('after_setup_theme', 'mythumbnails_setup');
幅と高さに 0 を指定したサイズは作られません。et-pb- で始まるサイズは、以前使っていたテーマ(Divi)が登録していたものです。テーマを替えても設定が残っていることがあるので、まとめて止めています。
残すのは、次の3つだけです。
| サイズ名 | 大きさ | 用途 |
|---|---|---|
| thumbnail | 300×300(切り抜き) | 管理画面のメディア一覧 |
| medium_large | 幅 768px | 一覧ページ |
| large | 幅 1200px | 記事の本文 |
「設定 › メディア」の数値は使わない
add_image_size() で登録したサイズは、管理画面の「設定 › メディア」の数値より優先されます。画面の数値を変えても反映されないので、迷わないように画面に案内を出しています。
//メディア設定画面に、画像サイズをテーマ側で管理している旨を表示する
function media_settings_notice() {
$screen = get_current_screen();
if (!$screen || $screen->id !== 'options-media') return;
echo '<div class="notice notice-info"><p>'
. '画像サイズは <code>themes/zaratan/functions.php</code> の <code>mythumbnails_setup()</code> で管理しています。'
. 'この画面の数値を変更しても反映されません。'
. '</p></div>';
}
add_action('admin_notices', 'media_settings_notice');
2560px を超える画像は EWWW で縮小する
WordPress 本体は、2560px を超える画像をアップロードすると、元画像を残したまま -scaled という縮小版を作ります。この記事の構成では、EWWW の「最大画像サイズ」で元画像そのものを 2560px までに縮小するので、本体の機能は止めています。
//2560px以上の画像(scaled)の自動生成を停止
add_filter('big_image_size_threshold', '__return_false');
メディア挿入時の初期サイズを「大」に固定する
縮小版を作っても、記事に「フルサイズ」で挿入されると、2560px の画像が読み込まれます。実際に、ニュース記事の写真が size-full で挿入されていました。
WordPress は、メディアを挿入するときに前回選んだサイズを覚えていて、次回もそのサイズを初期値にします。一度でも「フルサイズ」を選ぶと、それ以降もフルサイズが選ばれたままになります。そこで、次の2つを組み合わせて、毎回「大(large)」から始まるようにしました。
//メディア挿入時の画像サイズを、毎回「大(large)」にする
add_filter('pre_option_image_default_size', function () {
return 'large';
});
function reset_media_insert_size() {
?>
<script>
(function () {
function resetImgSize() {
if (typeof window.setUserSetting === 'function') {
window.setUserSetting('imgsize', 'large');
}
}
//管理画面を開いたとき
resetImgSize();
//メディアの追加画面(モーダル)を開くたび
if (window.wp && wp.media && wp.media.view && wp.media.view.Modal) {
var originalOpen = wp.media.view.Modal.prototype.open;
wp.media.view.Modal.prototype.open = function () {
resetImgSize();
return originalOpen.apply(this, arguments);
};
}
})();
</script>
<?php
}
add_action('admin_print_footer_scripts', 'reset_media_insert_size', 99);
pre_option_image_default_size は、WordPress の既定の挿入サイズ(image_default_size)を large に固定するフィルターです。「設定 › メディア」には、この値を変える項目がありません。
前回選んだサイズは、ユーザー設定の imgsize に保存されていて、既定値より優先されます。そこで、管理画面を開いたときと「メディアを追加」の画面を開くたびに、setUserSetting('imgsize', 'large') で「大」に戻しています。記事の作成中に別のサイズを選ぶことはできますが、次に画面を開いたときは「大」から始まります。
なお、幅が 1200px 未満の画像には「大」の縮小版が作られないので、その場合は WordPress が自動でフルサイズを使います。
srcset で画面に合ったサイズを表示する
本文に画像を挿入すると、WordPress は srcset と sizes を自動で付けます。ブラウザは、画面の幅と解像度に合わせて、srcset の中から、表示に足りる最小のサイズを選びます。
<img src="…/photo-1200x800.jpg"
srcset="…/photo-1200x800.jpg 1200w, …/photo-768x512.jpg 768w, …/photo.jpg 2560w"
sizes="(max-width: 1200px) 100vw, 1200px"
class="size-large wp-image-123" …>
ここで重要なのは、sizes の上限です。「大」で挿入すると上限が 1200px になり、スマホでは 768px などの小さい画像が選ばれます。「フルサイズ」で挿入すると上限が 2560px になり、高解像度の PC では 2560px の画像が選ばれてしまいます。初期サイズを「大」に固定しているのは、このためです。
すでにフルサイズで挿入した画像は、挿入し直すか、本文の size-full を size-large に、画像の URL を -1200x800 などの縮小版に変えると、「大」と同じ扱いになります。
保存時に自動で付けている属性
テーマでは、投稿を保存するときに、本文の画像へ2つの属性を自動で付けています(content_save_pre フィルター)。
| 処理 | 内容 | 目的 |
|---|---|---|
| キャッシュ対策の日時 | 画像 URL の末尾に ?ver=保存日時 を付ける(既存の ver= は付け直す) |
画像を差し替えたとき、ブラウザやキャッシュに古い画像が残らないようにする |
| aspect-ratio | 実際の画像の寸法から style="aspect-ratio:幅/高さ" を付ける |
画像の読み込み前に表示領域を確保し、レイアウトのずれ(CLS)を防ぐ |
そのため、本文を変えずに「更新」を押しただけでも、リビジョンには ver= の日時の差分が残ります。変更内容をリビジョンで確認するときは、この差分を除いて見ると、実際の変更がわかります。
テーマ内の画像は、表示幅の2倍を目安に縮小する
メディアライブラリを通さない、テーマの images フォルダの画像は、手作業で縮小します。目安は「サイト上の表示幅の2倍」です。高解像度の画面でも粗く見えず、それ以上大きくしても見た目はほとんど変わりません。
実際に縮小を試した結果です(作業用のコピーで試算)。
| 画像 | 元の大きさ | 表示幅(PC/スマホ) | 縮小後 | 容量 |
|---|---|---|---|---|
| 施工実績の写真(6枚) | 3000×2000px | 291px/303px | 800×533px | 計 2,783KB → 約680KB(約75%減) |
| 写真を PNG で保存していた画像 | 980×700px | 525px/303px | 同じ大きさで JPG に変換 | 322KB → 150〜200KB |
| トップの背景写真 | 4000×2060px | 1261px/360px | 2560px に縮小 | 631KB → 514〜768KB(減らないことがある) |
試してわかったことが2つあります。
- 元の画像がすでに強めに圧縮されている場合は、縮小しても容量があまり減りません。保存し直すときの品質が元より高いと、かえって増えることもあります。縮小後の容量は、必ず元と比べます
- PNG は、macOS の
sipsなどで縮小しても最適化されないので、容量が増えることがあります。PNG は、ImageOptim などの最適化ツールを通すか、図であれば SVG にします
表示幅は、ブラウザの開発者ツールで画像を選び、表示されているサイズを見て確認します。PC とスマホでレイアウトが違うので、両方の幅で確認します。
最初の画面の画像は遅延読み込みしない
テーマでは、画像の遅延読み込みを JavaScript(class="lazy" と data-src 属性)で行っています。画面に近づいたときに、data-src の URL を src に入れて読み込む仕組みです。
この仕組みは、ページの最初の画面に表示される画像には使いません。HTML に本物の URL を書いておけば、ブラウザは HTML を読み込んだ直後に画像の取得を始められます。遅延読み込みの画像に fetchpriority="high" を付けても、JavaScript が src を入れるまで取得が始まらないので、効果はありません。
実際に計測したところ、最初の画面の画像は約 0.3 秒で取得が始まっていましたが、LCP(最も大きい要素が表示される時刻)は約 2.3 秒でした。原因は画像ではなく、ページ全体を覆う読み込み中の表示(スピナー)が、一定時間たつまで消えない作りだったことです。表示速度を見直すときは、画像だけでなく、こうした演出の待ち時間も確認します。
alt 属性の付け方
画像のサイズと合わせて、alt 属性も見直しました。
| 画像の種類 | alt | 例 |
|---|---|---|
| 内容のある写真 | 写真の内容を短く書く | alt="管理しているオフィスビルの外観" |
| 文字が書かれた画像(図表・数値・見出し) | 画像の中の文字をそのまま書く | alt="従業員数〇〇人、平均年齢〇〇歳…" |
| リンクの中の画像だけのボタン | リンク先がわかる言葉 | alt="募集要項・エントリー" |
| 装飾の画像 | 空にする | alt="" |
| 画像がないときの代わりの画像 | 空にする | alt=""(alt="NoImage" にしない) |
数値やグラフが画像の中にしかないと、検索エンジンはその内容を読み取れません。表やグラフは、できれば HTML のテキストにし、すぐに直せないときは alt に中身を書きます。
まとめ
- 画像サイズは
functions.phpで必要なものだけを登録し、「設定 › メディア」の数値は使わない - アップロード時の縮小(2560px)と圧縮は EWWW に任せる
- メディア挿入時の初期サイズを「大」に固定し、本文の画像は 1200px を上限にする
- テーマ内の画像は表示幅の2倍を目安に縮小し、縮小後の容量を必ず確認する
- 最初の画面の画像は遅延読み込みせず、alt には画像の中身を書く
EWWW Image Optimizer の各タブの設定は、「EWWW Image Optimizerの設定|無料版で画像を自動圧縮・WebP化する手順」で画面つきで紹介しています。
関連記事
EWWW Image Optimizerの設定|無料版で画像を自動圧縮・WebP化する手順 | CODE-PLUS(コードプラス) WordPressの画像最適化プラグイン「EWWW Image Optimizer」を無料版で使うときの設定を、タブごとに画面つきで解説します。最大画像サイズ2560px、ピクセルパーフェクト圧縮、WebP変換とリライトルールの設定、有料の「簡単I... 続きを読む 画像のアスペクト比を自動計算・付与する | aspect-ratioが効かない原因とCLS対策 | CODE-PLUS(コードプラス)