ピクセル比3倍のデバイスで
画像表示を2倍サイズまでに
留める方法
最新のRetinaのようなデバイスピクセル比が3倍のデバイスで、
srcset sizes属性でレスポンシブを行うと
実際の表示サイズの3倍の画像を表示させようとして、大きすぎる画像を読み込む。
そのため表示スピードが遅くなるので、
表示スピードを早めるためにデバイスピクセル比が3倍のデバイスでは、
sizesを66%にして、2倍サイズの画像を読み込ませる。
これでdomを減らしながらpicture属性と同じように
表示させる画像をデバイス側に依存せずにコントロールできる。
2-2-2カラム
■変換前の記述
<div class="main-inner flex">
<div class="flex-2-2-2">
<img decoding="async" loading="lazy" data-srcset="
https://example.com/img/img-2-2-2-384-216.jpg 384w,
https://example.com/img/img-2-2-2-416-234.jpg 416w,
https://example.com/img/img-2-2-2-928-522.jpg 464w,
https://example.com/img/img-2-2-2-928-522.jpg 928w"
src="https://example.com/img/spacer.png"
data-src="https://example.com/img/img-2-2-2-928-522.jpg"
alt="テスト画像" width="928" height="522" class="lazyload ar16-9 fadein"
data-sizes="
(max-width:416px) 192px,
(max-width:464px) 208px,
464px">
</div>
</div>
■変換後の記述
<div class="main-inner flex">
<div class="flex-2-2-2">
<img decoding="async" loading="lazy" data-srcset="
https://example.com/img/img-2-2-2-384-216.jpg 384w,
https://example.com/img/img-2-2-2-416-234.jpg 416w,
https://example.com/img-2-2-2-928-522.jpg 464w,
https://example.com/img-2-2-2-928-522.jpg 928w"
src="https://example.com/img/spacer.png"
data-src="https://example.com/img-2-2-2-928-522.jpg"
alt="テスト画像" width="928" height="522" class="lazyload ar16-9 fadein"
data-sizes="
(max-width:416px) and (max-resolution:2dppx) 192px,
(max-width:416px) and (min-resolution:3dppx) calc(192px * 0.66),
(max-width:464px) and (max-resolution:2dppx) 208px,
(max-width:464px) and (min-resolution:3dppx) calc(208px * 0.66),
(max-resolution:2dppx) 464px,
(min-resolution:3dppx) calc(464px * 0.66)">
</div>
</div>
●ウィンドウサイズ416px以下で、デバイスピクセル比「2」以下の時に表示させる画像
(max-width:416px) and (max-resolution:2dppx) 192px
●デバイスピクセル比「3」以上なら画像表示サイズを66%(ピクセル比3→ピクセル比2換算)縮小して表示させる
(max-width:416px) and (min-resolution:3dppx) calc(192px * 0.66)
●ウィンドウサイズ464px以下で、デバイスピクセル比「2」以下の時に表示させる画像
(max-width:464px) and (max-resolution:2dppx) 208px
●デバイスピクセル比「3」以上なら画像表示サイズを66%(ピクセル比3→ピクセル比2換算)縮小して表示させる
(max-width:464px) and (min-resolution:3dppx) calc(208px * 0.66)
●ウィンドウサイズ465px以上で、デバイスピクセル比「2」以下の時に表示させる画像
(max-resolution:2dppx) 464px
●デバイスピクセル比「3」以上なら画像表示サイズを66%(ピクセル比3→ピクセル比2換算)縮小して表示させる
(min-resolution:3dppx) calc(464px * 0.66)
■function.phpでの一括置換処理
<?php
//■srcset/sizesの属性でピクセル比3倍のデバイスでも3倍の画像を表示させず、sizesを2/3倍にして2倍の画像を表示させる。
function PixelRatio_Control($pixel_ratio_branch) {
if(
is_page() || is_single() //固定ページと投稿ページのみ
&& !is_admin() //管理画面以外
&& $pixel_ratio_branch != null //値が空でない
){
$pattern = array('/(.*?)(\(\s*(max|min)-width\s*:\s*\d+px\s*\))\s*(\d+px)\s*,\s*(.*?)/', '/(<img.*?)(calc\(\s*\d+px\s*\*\s*0.66\s*\)\s*,\s*)(\d+px)\s*[\"|\']/' );
$replace = array('$1$2 and (max-resolution:2dppx) $4, $2 and (min-resolution:3dppx) calc($4 * 0.66), $5', '$1$2(max-resolution:2dppx) $3, (min-resolution:3dppx) calc($3 * 0.66)"' );//置換
$pixel_ratio_branch = preg_replace($pattern, $replace, $pixel_ratio_branch);
}
return $pixel_ratio_branch;
}
add_filter('the_content', 'PixelRatio_Control', 12 );
?>
●元の記述
sizes="(max-width:416px) 192px, (max-width:464px) 208px, 464px"
●変換1段階目
sizes="(max-width:416px) and (max-resolution:2dppx) 192px, (max-width:416px) and (min-resolution:3dppx) calc(192px * 0.66), (max-width:464px) and (max-resolution:2dppx) 208px, (max-width:464px) and (min-resolution:3dppx) calc(208px * 0.66), 464px"
変換する対象文字列(max-width:416px) and (max-resolution:2dppx) 192px, (max-width:416px) and (min-resolution:3dppx) calc(192px * 0.66),
を対象とし、正規表現を使って複数置換。
「max-width」のついた項目を複製。
「max-resolution」の項目を追加。
複製した項目にのみcalcの計算式を追加。
●変換2段階目
sizes="(max-width:416px) and (max-resolution:2dppx) 192px, (max-width:416px) and (min-resolution:3dppx) calc(192px * 0.66), (max-width:464px) and (max-resolution:2dppx) 208px, (max-width:464px) and (min-resolution:3dppx) calc(208px * 0.66), (max-resolution:2dppx) 464px, (min-resolution:3dppx) calc(464px * 0.66)"
■正規表現での置換(変換1段階目)の詳細
●対象文字列(変換1段階目)
<img decoding="async" loading="lazy" data-srcset="
https://example.com/img/img-2-2-2-384-216.jpg 384w,
https://example.com/img/img-2-2-2-416-234.jpg 416w,
https://example.com/img/img-2-2-2-928-522.jpg 464w,
https://example.com/img/img-2-2-2-928-522.jpg 928w"
src="https://example.com/img/spacer.png"
data-src="https://example.com/img/img-2-2-2-928-522.jpg"
alt="テスト画像" width="928" height="522" class="lazyload ar16-9 fadein"
data-sizes="(max-width:416px) 192px, (max-width:464px) 208px, 464px">
※赤字の箇所を置換する。
●正規表現(変換1段階目)
(.*?)(\(\s*(max|min)-width\s*:\s*\d+px\s*\))\s*(\d+px)\s*,\s*(.*?)
最初の(.*?)
は冒頭の文字列「<img … data-sizes="
」をまでグループ化した意味。
\(
は括弧「(」の意味。
\s*
は半角スペースの意味。
(max|min)
は「max」または「min」の意味。
:
コロンはエスケープしなくてよい。
\d+
は半角英数字の意味。
\)
は閉じ括弧「)」の意味。
,
カンマはエスケープしなくてよい。
最後の(.*?)
は残りの文字列「464px">」
をグループ化した意味。
●置換の記述(変換1段階目)
$1$2 and (max-resolution:2dppx) $4, $2 and (min-resolution:3dppx) calc($4 * 0.66), $5
$1
は冒頭の文字列<img … data-sizes="
$2
は(max-width:416px)
と(max-width:464px)
※複数変換
$3
はmax
※使ってない
$4
は192px
と208px
※複数変換
$5
は残りの文字列464px">
■正規表現での置換(変換2段階目)の詳細
●対象文字列(変換2段階目)
<img decoding="async" loading="lazy" data-srcset="
https://example.com/img/img-2-2-2-384-216.jpg 384w,
https://example.com/img/img-2-2-2-416-234.jpg 416w,
https://example.com/img/img-2-2-2-928-522.jpg 464w,
https://example.com/img/img-2-2-2-928-522.jpg 928w"
src="https://example.com/img/spacer.png"
data-src="https://example.com/img/img-2-2-2-928-522.jpg"
alt="テスト画像" width="928" height="522" class="lazyload ar16-9 fadein"
data-sizes="(max-width:416px) and (max-resolution:2dppx) 192px, (max-width:416px) and (min-resolution:3dppx) calc(192px * 0.66), (max-width:464px) and (max-resolution:2dppx) 208px, (max-width:464px) and (min-resolution:3dppx) calc(208px * 0.66), 464px">
※赤字の箇所を置換する。
●正規表現(変換2段階目)
(<img.*?)(calc\(\s*\d+px\s*\*\s*0.66\s*\)\s*,\s*)(\d+px)\s*[\"|\']
2段階目の置換は1段階目でできたcalc(208px * 0.66), 464px"
を正規表現で割り出して464px
部分のみを置換する。
最初の(<img.*?)
は終盤の記述calc(208px * 0.66), 464px"
を除く、冒頭の文字列「<img … (min-resolution:3dppx)
」までをグループ化した意味。
\(
は括弧「(」の意味。
\s*
は半角スペースの意味。
\d+
は半角英数字の意味。
\*
は「*」の意味。
\)
は閉じ括弧「)」の意味。
,
カンマはエスケープしなくてよい。
[\"|\']
は「"」または「’」の意味。
●置換の記述(変換2段階目)
$1$2(max-resolution:2dppx) $3, (min-resolution:3dppx) calc($3 * 0.66)"
$1
は冒頭の文字列<img … (min-resolution:3dppx)
$2
はcalc(208px * 0.66),
$3
は464px