WordPressとsrcsetのメディアな関係

WordPressとsrcsetのメディアな関係

2018年9月25日

読み込む画像をレスポンシブに変えてくれるという、imgタグのsrcset。
WordPressでも4.4から自動的に追加されるようになっていたのですが、意外とクセモノでした。

[Ad]

srcsetが追加されたりされなかったりしている?

WordPress4.4から、the_post_thumbnail()でアイキャッチ画像を表示していると、imgタグにsrcsetが追加されるようになっていたようです。

普段から触っているのに、追加されていることに気付かなかった理由は、仕事で普段から触っているサイトAに追加されてなかったから。
しかし、新しく管理することになったサイトBの表示確認をしていたところ、こちらには追加されていたんですね。

WPのバージョンも同じ最新だし、テンプレートもほぼ同じもの。何が違うのか色々調べていたところ、違うものが1つありました。
メディアの設定です。

WordPressのsrcsetはメディア設定に依存しているらしい

当ブログの場合、メディア設定がこんな感じなんですが、

the_post_thumbnail()で出力したコードをみると、

<img width="700" height="450"
 src="https://memo.ark-under.net/wp/wp-content/uploads/nissaba00.jpg" alt=""
 srcset="https://memo.ark-under.net/wp/wp-content/uploads/nissaba00.jpg 700w,
         https://memo.ark-under.net/wp/wp-content/uploads/nissaba00-350x225.jpg 350w"
 sizes="(max-width: 700px) 100vw, 700px">

サムネイルサイズと中サイズのファイル名が入ってるやんけ!
しかも、メディア設定で指定した横幅がブレイクポイントになってるし!
↑の例だと、アップした画像が700pxの画像なので大サイズは追加されていませんが、アップした画像が1024px以上だった場合は、大サイズの画像も追加されます。

※srcsetについてはこの記事が分かりやすいです。

実はサイトAの方、サイトの立ち上げ当初から余計なサイズのファイルを作りたくないという理由からと、メディア設定で中サイズと大サイズに「0」を指定してたんです。こうすると、サムネイルサイズと元データ以外のファイルはサーバーに保存されません。
改めてサイトBのメディア設定を確認すると、きちんと「0」以外が設定されていました。
どうやらそれが理由で、サイトAではsrcsetが追加されていなかったようです。

メディア設定に関わらずsrcsetを設定したい場合

レスポンシブに読み込む画像を変えてくれるsrcsetですが、WordPressで自動的に付与される方法だとブレイクポイントがCSSと合わない、ということもあると思います。
また、add_image_size()などで追加したサイズの画像を使いたいという場合もありますよね。

そんな時の場合のスニペットを作りました。
以下はfunctions.phpに追加してください。

//srcsetをつけた画像タグをつくる
function custom_post_thumbnail($ID, $size=NULL){
    $thumbnail_id = get_post_thumbnail_id($ID); //アタッチメントIDの取得
    If(!$thumbnail_id){
        //アイキャッチ画像がなければnoimageを表示
        echo '<img src="'.get_template_directory_uri().'/img/noimage.jpg" />’;
    }else{
        if(!$size){$size = ‘full';} //指定がなければ「full」を指定
        $largeImage = wp_get_attachment_image_src( $thumbnail_id, $size );
        $smallImage = wp_get_attachment_image_src( $thumbnail_id, ’thumbnail' );
        //srcsetの内容を作成
        $srcsetData = $largeImage[0].' 640w, '.$smallImage[0].' 380w’;
        //srcの画像URLを指定
        $src = $largeImage[0];
        echo '<img src="'.$src.'" srcset="'.$srcsetData.'" sizes=“100vw" />’;
    }
}

12行目のsrcsetの内容を作成する部分で、任意のブレイクポイントにすることができます。
そしてこれを、the_post_thumbnail()の代わりにループ内で使います。

<?php $postid = get_the_ID(); custom_post_thumbnail($postid,’full'); ?>

自由にsrcsetを設定できたものの…

これでWordPressでも上手くsrcsetを使いこなせるぞ!と思ったのですが、問題点が出てきました。

モバイルでの表示速度をチェックするtestMySiteや、PageSpeed Insightsの結果が変わらないのです。。。

PCでは大きいサイズ、SPでは小さいサイズの画像をsrcsetで表示するようにしましたが、大きいサイズでの読み込みになってしまうんです。
srcに指定する画像を小さいサイズにしてみても変化なし。

色々調べたところ、どうやらChromeはsrcsetの挙動がまだ不安定みたいなんですね。
この記事の半ばあたりに各ブラウザでの挙動が書いてあります。2017年7月時点での挙動だそうですが、この記事を書いている現時点でもまだ不安定な感じです。

手持ちのiPhoneで確認した限りでは上手く動いていましたが、testMySiteで上手くいっていないのであれば、ちょっと自信なくなりますよね。
testMySiteが検証で使用しているブラウザは、Moto G4のChromeということなので、Androidの場合の挙動は違うかもしれないし…。

もともとsrcsetで表示スピードを改善しようと思って調べていたのがきっかけで、しかも採用しようと思っていたサイトは海外向けのサイト。
世界で見ると、iPhoneよりAndroidの方がシェアは高いそうなので、srcsetを使わない形で表示スピードの改善をすることにしました。

ユーザーエージェントで画像サイズを振り分ける

srcsetを使わず、画像の読み込みを変えるとなると、もうこの方法しかないですよね。
コードとしては、こんな感じになりました。functions.phpに記述して使用します。

//UAで画像を出し分ける
function custom_post_thumbnail($ID, $ua, $size=NULL){
    $thumbnail_id = get_post_thumbnail_id($ID);
    if(!$size){$size = 'full';}
    if(!$thumbnail_id) {
    //アイキャッチ画像がない場合
        $src = get_template_directory_uri().'/img/noimage.jpg"';
        $width = 640;    $height = 400;
    }else{
        // SP & Tablet
        if ((strpos($ua, 'Android') !== false) && (strpos($ua, 'Mobile') !== false) || (strpos($ua, 'iPhone') !== false) || (strpos($ua, 'Windows Phone') !== false) || (strpos($ua, 'iPad') !== false)) {
            $image = wp_get_attachment_image_src( $thumbnail_id, ’thumbnail' );
        // PC
        } else {
            $image = wp_get_attachment_image_src( $thumbnail_id, $size );
        }
        $src = $image[0]; //url
        $width = $image[1]; //横幅
        $height = $image[2]; //高さ
    }
    echo '<img src="'.$src.'" width="'.$width.'" height="'.$height.'" />';
}

表示させるテンプレートの最初の方で、以下のようにユーザーエージェントを取得しておきます。

<?php $ua = $_SERVER['HTTP_USER_AGENT']; ?>

そして、表示させるループ内ではこんな感じで追加します。

<?php $postid = get_the_ID(); custom_post_thumbnail($postid,$ua,’full'); ?>

とりあえずはこんな感じで、表示スピードの改善はなんとかできました。
Retinaディスプレイなどを考えると、srcsetで追加しておくことも重要かなと思いますが、小さい表示で使用する分には、こういう方法でもいいのかなと。
srcsetのChromeでの挙動が安定したら、また利用を考えたいと思います。