【pug】pictureタグでwebpを使うためのオススメmixin紹介

こんにちは!のせっち@nosecchi01です。

pugのmixinを使えば、webpの出し分けを簡単に行えるので紹介します。

サイトスピードにおける画像処理の重要性

画像はサイトスピードにおいて最重要事項と言えます。

Google Page Speed Insightsに少しでも向き合ったことがある人ならわかると思いますが、サイト軽量化の一丁目一番地は画像です。

一口に画像と言っても、対応しなければならないことは多数あります。

  1. 適切なサイズで書き出す
  2. 画像の圧縮を行う
  3. webpを使う(軽量かつ劣化の少ない拡張子の使用)
  4. width, heightを書く(Contents Layout Shift対応)

本記事は3、4の解説記事です。

webpを使う

画像圧縮を行なっていることは大前提として、次世代拡張子を使うことも重要になってきました。

具体的にはwebpです。

webpとは
Googleが開発したWebサイト向けの拡張子で、圧縮率が高く、かつ画質劣化の少ない次世代の拡張子です。

対応ブラウザも順次増えてきていますが、まだ対応しきれていないブラウザもあるので、webp対応でない場合は従来のjpg, pngなどの拡張子を出してあげる、という出し分けが重要となります。

Contents Layout Shiftに対応する

近年ではCore Web Vitalsも重要となってきていて、中でもContents Layout Shiftの減点は痛いです。

Contents Layout Shift(CLS)とは
画像に関係するところでいえば、画像の読み込み前と、読み込み後で画像の高さが変わって、レイアウトが変化してしまうことです。レイアウトシフトが大きいほど「ユーザー体験が悪い」という評価で減点になります。

Google Developersより:レイアウトシフトに関する記述

lazyloadを使う場合顕著に出ます。

解決策としては、imgタグにwidth, heightを書いてあげることです。
sourceタグもwidth,heightを書くことができるようになったので両方に書きます。

pictureタグをmixin化する重要性(めんどくさいから)

  • pc、spでの画像出し分け(本来の役割)
  • webpとpng/jpgの出し分け
  • 全てのsourceタグ、imgタグにwidth, heightを書く

これを毎回手で書くのはどう考えても面倒です。
そこで、pugのmixinに書いておき、どこでも呼び出せるようにしてあげます。

mixinの紹介

下記のようなmixinを作ります。

mixin webpImg(className, imgName, extension, altName, smp, widthSp, heightSp, widthPc, heightPc)
  picture(class=className)
    if (smp === true)
      source(
        media="(min-width: 768px)",
        srcset=imgPath + imgName + ".webp",
        width=widthPc,
        height=heightPc,
        type="image/webp"
      )
      source(media="(min-width: 768px)", srcset=imgPath + imgName + "." + extension, width=widthPc, height=heightPc)
      source(
        media="(max-width: 767px)",
        srcset=imgPath + imgName + "-smp" + ".webp",
        width=widthSp,
        height=heightSp,
        type="image/webp"
      )
      img(
        src=imgPath + imgName + "-smp" + "." + extension,
        width=widthSp,
        height=heightSp,
        alt=altName,
        loading="lazy"
      )
    else
      source(srcset=imgPath + imgName + ".webp", type="image/webp")
      img(src=imgPath + imgName + "." + extension, width=widthSp, height=heightSp, alt=altName, loading="lazy")

あとは、呼び出します。

ほぼwepImg()の引数で指定するのですが、imgPath(画像フォルダの場所)は定義しておかないといけません。

include _mixin
- const path = ".";
- const imgPath = path + "/img/"; //- 画像フォルダの場所。説明簡略化のためindex.pugで定義しています。

+webpImg("hoge", "cat/img-cat", "jpg", "サンプル画像", true, "375", "600", "1280", "400")

コンパイル後

<picture class="hoge">
    <source media="(min-width: 768px)" srcset="./img/cat/img-cat.webp" width="1280" height="400" type="image/webp">
    <source media="(min-width: 768px)" srcset="./img/cat/img-cat.jpg" width="1280" height="400" type="image/jpg">
    <source media="(max-width: 767px)" srcset="./img/cat/img-cat-smp.webp" width="375" height="600" type="image/webp">
    <img src="./img/cat/img-cat-smp.jpg" width="375" height="600" type="image/jpg" alt="サンプル画像" loading="lazy">
</picture>

imgPathをindex.pugで定義しています。
(本来定義部分は別ファイルに分けるのですが、説明を簡略化するためです。)

詳しくは下記の記事をどうぞ!pugを効率よく書くための解説記事です。

簡単な解説

webpImg(className, imgName, extension, altName, smp, widthSp, heightSp, widthPc, heightPc)に必要な引数を渡してあげます。

  • className:クラス名
  • imgName:画像のパスを指定
  • extension:拡張子を指定(jpg or png)
  • altName:altに入れる内容を指定
  • smp:pc/spで画像の出し分けがある場合はtrue、なければfalseを指定
  • widthSp:SP時のwidthを指定
  • heightSp:SP時のheightを指定
  • widthPc:PC時のwidthを指定
  • heightPC:PC時のheightを指定

これでsourceタグ、imgタグに引数が入って、pictureタグが完成します。

sp用画像はimg-cat-smp.jpgなどpc画像ファイル名 + -smpとしてください。

smpfalseにした場合はwebpの出し分けのみを行なってくれます。

<!-- smpをfalseにした場合のhtml出力例 -->
<picture class="hoge">
    <source srcset="./img/cat/img-cat.webp" type="image/webp">
    <img src="./img/cat/img-cat.jpg" width="375" height="600" alt="サンプル画像" loading="lazy">
</picture>

実務レベルでは不要と思いますが、1x 2xなどの出し分けもやろうと思えば可能です。
ご自身でアレンジしてみてください!

まとめ

  • 画像軽量化の一貫としてwebpを使うことが重要。
  • Contents Layout ShiftはGoogleが厳しく見ており、width, heightを書いておくことが重要。
  • pugのmixinを使わないとやってられない。

この記事を書いた人

のせっち

福岡県出身。早稲田大学卒。創業100年の鉄鋼商社でバンコク駐在最年少抜擢。毎日擦り切れるまで働かなくても幸せに生きている人々を見てフリーランスになりました。
- WordPressが得意!
- 初心者向けGulp教材は購入者100部以上!