画像遅延ロード Lazy Load (Unveil.js) で体感表示スピードアップ!

画像遅延ロード

画像が多くサイトの表示が遅い時に Lazy Load  という jQuery のプラグインを使用すると、読み込みスピードが速くなるらしいと言うのを聞いて調べてみました

仕組み

どのようなカラクリかというと、画像を表示する img タグ要素の src に 1×1 ピクセル等のサイズの小さなダミー画像に設定しておいて、ブラウザでのファーストビュー表示を終了させてから、jQuery により本来の画像に後から書き換える(遅延ロード)ことで体感スピードをアップさせます

ファーストビューに表示されていない画像に関しては、スクロールに応じて必要なタイミングで画像をロードして表示します

従って、実際にブラウザに画像を表示するまではロードしないという効率的な仕組みです

Unveil Lazy Load

今回は、遅延ロード時にエフェクト等は必要ないので、lazy Load の軽量版 Unveil.js を使用してみました

luis-almeida/unveil · GitHub

画面右下の Download ZIP ファイルからダウンロードできます

ソースコードは 1K 以下という小ささです

使い方

unveil-usage

要約すると

img要素の src にダミー画像を指定して、data-src に遅延ロードする画像を記述します

また、data-src-retina には、Retinaディスプレイ用の画像も指定することが出来ます

後は、Unveil.js スクリプトを読み込み、$("img").unveil() で実行してやるだけです

オプション
threshold 遅延ロードの閾値
$(“img”).unveil(200) とするとブラウザに表示される 200px 手前でロードされる
callback 画像がロードされるときに実行するコールバック関数
CSS3やjQueryで表示エフェクトを行うときに使用
Trigger トリガーイベントによる画像ロード
$(“img”).trigger(“unveil”) により、必要な時に画像ロードさせる事が出来ます

Unveil を組み込む

WordPress を使用していれば、Lazy Load 関連のプラグインは沢山登録されています

その多くは jQuery の Lazy Load を使用して、PHP側の処理で imgタグ要素の書き換え処理を行っているだけなので、プラグインを使わなくてもテーマに簡単に組み込ムことが出来ます

当初は Celtis-one テーマに直接組み込んでいましたが、celtispack プラグインへ移しました

celtispack プラグインをインストールして Unveil Lazyload モジュールを有効化すると簡単に使用できるようになります

ダウンロードは、WordPress Plugin : Celtispack ページから行うことが出来ます

 

プラグインに組み込んだ時のポイントを紹介します

スクリプトの読み込み

おなじみの wp_enqueue_script を使用して unveil.js を読み込みます
プラグインパック中のモジュールとして実装しているため、ちょっと回りくどい書き方をしています (^_^;)

$path = __DIR__ . '/jquery.unveil_custom.js';
wp_enqueue_script( 'unveil-js', content_url() . str_replace('\\' ,'/', substr( $path, stripos($path, 'wp-content') + 10)), array('jquery'), NULL, true);
スレッシュホールドの指定

スクリプトが実行されるタイミングを設定します

0, 200, 400 と試してみましたが、400ぐらいにしておくと、環境にもよりますが、遅延ロードしているかどうかわからないぐらいにスムーズに表示出来ます

jQuery(document).ready(function($){
  $("img").unveil(400);
});
img タグの書き換え

遅延ロード用に img タグの src を書き換え、 data-src を追加します
この関数を add_filter で the_content にフィルターフックさせれば、コンテント内にある img タグの書き換えを行うことが出来ます

static function unveil_attribute($matches)
{
    //$matches[0]  img タグ全体
    //$matches[1]  src 前の記述
    //$matches[2]  src 本体 (置き換え用の画像には base64 1x1 px transparent gif image を指定)
    //$matches[3]  src 後の記述
    // data-src あれば unveil 記述済み、data-orig あれば Lazy Load 記述済み、wp.com あれば jetpack photon 用に書き換え済みなので除外
    // flex-slider の場合も除外する
    $content = $matches[0];
    if (preg_match("#\.png|\.gif|\.jpe|\.jpeg|\.jpg#i", $matches[2])){
        if (!preg_match("#data-src|data-orig|wp.com|slide-image#", $matches[0])){
            $content = '<img' . $matches[1] . 'src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAAAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==" ';
            $content .= 'data-src="' . $matches[2] . '"'. $matches[3]. '>';
            $content .= '<noscript>JavaScript is not working</noscript>';
        }
    }
    return $content;
}
    
public function unveil_lazyload($content)
{
    $content = preg_replace_callback('#<img([^>]+?)src=[\'"]?([^\'"\s>]+)[\'"]?([^>]*)>#', "Celtispack_unveil_lazyload::unveil_attribute", $content);  
    return $content;
}

少し解説すると

preg_replace_callback を使用して正規表現を用い img タグを取得し、分別します

img タグにマッチするとコールバック関数が呼ばれ、次のようにデータを取得できます

  • $matches[0]  img タグ全体
  • $matches[1]  src 前の記述
  • $matches[2]  src 本体
  • $matches[3]  src 後の記述

ここで $matches[3] 内に data-src が記述されていたら、その imgタグは既に unveil 対応の記述済みなので、書き換えを行わないでスキップします

注意点としては、img タグを書き換える他のプラグイン等と競合しないようにすることです

jetpack の tiled gallery や photon と競合する不具合があったので、wp.com をチェックしてスキップするようにしました。またアクセス解析等でも img タグを使用している場合があるようなので、画像の拡張子も合わせてチェックしていますが、これでも問題が発生する場合は、特定のサイトのみ除外する等の修正が必要になるかも知れません

それ以外は、src に置き換え用の base64 1×1 ピクセルの透過gif 画像を指定します

src=”data:image/gif;base64,R0lGODlhAQABAIAAAAAAAAAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==”

これは Data URI スキームと言って、小さな画像などを Base64 に変換し、HTMLやCSSに直接埋め込み、HTTPリクエストを減らして効率化するものです

Data URI scheme – Wikipedia – ウィキペディア

次に src に元々指定されていたデータを data-src に移します

他のアトリビュート要素等は、$matches[1], $matches[3] に入っていますのでそのままコピーして使用します

また、スクリプトが使用できない環境用に noscript タグを生成して、メッセージや img タグを追加します

ここでは、メッセージで済ませました (^^)

プログラムコードは、ダウンロードしたファイルの modules/unveil-lazyload/unveil-lazyload.php と jquery.unveil_custom.ja ファイルを参照してください

画像が多いページだとブラウザに最初に表示されるまでの時間が短縮されます
簡単に使えて、効果も大きいのでおすすめです

 

 


まとめ記事紹介

search star user home refresh tag chevron-left chevron-right exclamation-triangle calendar comment folder thumb-tack navicon angle-double-up angle-double-down angle-up angle-down quote-left googleplus facebook instagram twitter rss