お問い合わせはコチラから

【CLS対策】外部画像のimgタグにwidthとheightは必要?その方法は?

サイト運営

WordPress以前の時代では、外部画像をimgタグで直リンクするというのはよくある話でした。最近では、リンク先のサーバーに禁止されてできなくなっています。

アフィリエイトの場合、画像の直リンクを推奨しているところもあります。商品画像などを入れ替えたり、廃止商品になったりしたときに画像を使ってほしくない時に、サーバーの画像を入れ替えたり消したりすることで、ユーザーごとに対応せずに一括で処置できるからです。

しかし、外部画像を直リンクする時に問題となるのが、imgタグのwidthとheightのパラメータです。widthとheightはCLS対策として必須になっています。Wordpress内部の画像であれば勝手にwidthとheightが追加されますが、外部の画像については対象外です。

外部画像のサイズが固定であればまだ対策できますが、画像ごとにサイズが違うといちいち調べて手打ちするか、スクリプトで処置しなければ対応できなくなります。

この記事では、外部画像のimgタグのwithとheigthをどうやって調べて追加するかについてまとめています。

PHPを使ってwidthとheightを取得

WordPressサイトの場合は、PHPが使えます。PHPには画像サイズを取得する便利な関数があります。

getimagesize関数を使うと、画像のwidthとheightが取得できます。

PHP: getimagesize - Manual
PHP is a popular general-purpose scripting language that powers everything from your blog to the most popular websites i...

getimagesize使用例

$url = "hogehoge.com/img.jpg";
echo '<img '.getimagesize($url)[3].'src="'.$url.'"/>';

getimagesizeの問題点

使用する回数が増えると、外部との通信が増えて処置遅延が増えてきます。

10とか20個ぐらいになると数秒単位でサイトの表示が遅くなります。

使用できる回数は、1ページ当たり2~3個が限度ではないかと思います。

Javascriptを使ってwidthとheightを取得

Javascriptを使っても外部画像のwidthとheightを取得できます。そのまま、DOMを書き換えればimgタグのwidthとheightを設定することができます。

この方法は、サイトの表示速度に影響は出ないのですが、Lazyload対処でsrcが書き換えられたimgタグとの相性が悪いような気がします。

また、外部画像をlazyload前に読み込むのも効果を打ち消している気がします。

//関数定義
const myFunc = function(src){
    //Promiseオブジェクトを生成して返す
    return new Promise(function(resolve, reject){
        //Imageオブジェクトを生成
        const image = new Image();
        //読み込む画像を設定(関数の引数で取得した画像パスを代入)
        image.src = src;
        //onloadで画像読み込み完了後に処理
        image.onload = function(){
            //成功時にthenの処理へ
            resolve(image);
        }
        //onerrorで画像読み込みエラー時に処理
        image.onerror = function(error){
            //失敗時にcatchの処理へ
            reject(error);
        }
    });
}

//ページ内のimg要素を取得
const imgs = document.getElementsByTagName('img');

//img要素の数だけ繰り返し処理
for (const img of imgs) {
    //img要素のsrc属性の値を取得
    const src = img.getAttribute('src');
    
    //関数実行
    myFunc(src)
    //読み込みが完了した(画像が設定された)Imageオブジェクトを受け取って処理
    .then(function(res){
        
        //【追加】img要素にwidth属性が設定されていなければ処理
        if(!img.hasAttribute('width')){
            //img要素のwidth属性に値を設定
            img.setAttribute('width', res.width);
        }
        
        //【追加】img要素にheight属性が設定されていなければ処理
        if(!img.hasAttribute('height')){
            //img要素のheight属性に値を設定
            img.setAttribute('height', res.height);
        }
    })
    //画像読み込みエラー時の処理
    .catch(function(error){
        console.log(error);
    });
}

参考https://into-the-program.com/get-img-add-width-height-auto/

CSSだけで対応する

imgタグのwidthとheightは本当に必要なのでしょうか?

PageSpeedInsightの対策としてwidthとheightは必要ですが、CLSを悪化させないためだけであれば、外部画像のwidthとheightの正確な値は必要ありません。

画像を読み込む前後で要素の高さが変わらなければCLSは悪化しません。

そのための対策としては、以下の2つを行えばよいです。

  1. 画像をabsoluteにして、親要素いっぱいに広げる
  2. 親要素のアスペクト比を固定する(以下の例だと4:3)
  3. 画像を縮小したい場合は、画像の表示エリアを調整。
    親要素の高さもしくは画像のアスペクト比で調整する

アスペクト比の例

アスペクト比パーセント
16:956.25%
4:375%
3:266.666%
2:150%
<figure>
    <img src="xxx" width="100" height="100"/>
</figure>
figure{
    max-height: 500px; /*画像の幅を制限する*/
}
figure:before{
    padding-top: 75%; /*アスペクト比を指定*/
    content: "";
    display: block;
}
figure img{
    width: 100%;
    height: 100%;
    max-width: none;
    max-height: none;
    position: absolute;
    top: 0;
    object-fit: contain;
}

imgタグはposition:absoluteなのでサイズが”0″扱いになり、画像サイズはレイアウト崩れへの影響力が無くなります。

figureは子要素のimgタグが無くなり、figureの高さが決まらなくなります。そこで疑似要素を追加して、padding-topで高さを決めます。

imgタグは親要素全体に広がるので、画像の高さもそこで決まります。そうなると、外部画像のimgタグのwidthとheightはどんな値でもCLSに影響しなくなります。

まとめ

今回ご紹介したCSSを使う方法では、外部画像を直リンクして表示する際にwidthとheightの正確な値を知る必要はありません。

もしどうしても必要だとするなら処理速度やLazyload処理と相談して、javascriptかPHPで対応するしかないでしょう。

今回紹介したCSSによる方法を使わない場合に、widthやheightを固定値で決め打ちするとCLSも悪化しますし、目次からスムーススクロールする際にも飛び先がずれてしまう問題が起きやすいです。

この記事を書いた人
ブーン

はるばる日本よりオランダ王国へやってまいりました。
自分の経験が少しでも参考になれば嬉しいです。
お問い合わせは、『こちら』からお願い致します。

\ブーンをフォロー/
スポンサーリンク
サイト運営
\シェアお願いします!/
\ブーンをフォロー/
こんな記事も読まれています

失敗しないレンタルサーバーランキング

mixhost

不正アクセスに強くて使いやすいおススメサーバー
\本サイトで利用中/
メリット①:自動ウィルス駆除対応
メリット②:サイトの表示速度が速い!
メリット③:転送量の上限が多い!
メリット④:自由にプラン変更ができ、アクセス増にも対応できる!
メリット⑤:バックアップデータが無料で復元できる!
メリット⑥:Wordpressが簡単にインストールできる!
メリット⑦:どのプランでも初期費用が無料!
メリット⑧:10日間の無料お試し期間と30日の返金保証!

Conoha Wing

国内Wordpress最速の最強サーバー
メリット①:圧倒的な表示速度
メリット②:レンタルサーバーと独自ドメインがセットでお得◎
メリット③:プラン変更はすべてのプランで自由自在
メリット④:一か月の利用転送量の制限が緩い(9TB~)
メリット⑤:WordPresサイトの移行が簡単

エックスサーバー

国内シェアNo1の安定性と実績が魅力。ALL SSDで死角なしの万能サーバー。
メリット①:サイトの表示速度が安定して速い!
メリット②:アクセス負荷に強くて安定性が高い!
メリット③:24時間365日の充実サポートで安心!電話サポートもあり!
メリット④:転送量が多い!
メリット⑤:自動バックアップ機能付き!
メリット⑥:WordPressが簡単にインストールできる!
メリット⑦:10日の無料お試し期間がある!

タイトルとURLをコピーしました