見出し画像

lazyload(lazysizes)による画像の遅延読み込み

画像などを遅延読み込みをするlazyloadを使った手法をご紹介します。
今回はlazyloaderの中でも軽量なlazysizesというライブラリを使った方法で話します。

1.ライブラリを読み込ませる

<script src="lazysizes.min.js" async></script>

lazysizes.min.jsを読み込ませる。lazysizesの実行タイミングをwindowのloadイベント時に移したい場合は、ライブラリの記述を変更する必要があります。

変更前

(function(window, factory) {
 var lazySizes = factory(window, window.document);
 window.lazySizes = lazySizes;
 if(typeof module == 'object' && module.exports){
   module.exports = lazySizes;
 }
}(window, function l(window, document) {

変更後

(function(window, factory) {
 if( window.addEventListener ){
   window.addEventListener( 'load', doLazy, false );
 }else if( window.attachEvent ){
   window.attachEvent( 'onload', doLazy );
 }else{
   window.onload = doLazy;
 }
 function doLazy(){
   var lazySizes = factory(window, window.document);
   window.lazySizes = lazySizes;
   if(typeof module == 'object' && module.exports){
     module.exports = lazySizes;
   }
 };
}(window, function l(window, document) {

2.imgタグの属性を変更する

<img src="data:image/gif;base64,R0lGODlhAQABAGAAACH5BAEKAP8ALAAAAAABAAEAAAgEAP8FBAA7" data-src="imageurl.jpg" class="lazyload">

遅延読み込みを適用したい画像の<img>タグのclassにlazyloadを、src属性にはダミー画像を、data-src属性に表示させる画像を設定します。

ダミーで使っているdata:image/gif;base64,R0lGODlhAQABAGAAACH5BAEKAP8ALAAAAAABAAEAAAgEAP8FBAA7というURLはbase64というデータ形式で1×1pxの透過gif画像を直接HTMLに文字列で埋め込んでいます。リクエストが発生しないので、この形式がいいと思います。

ダミー画像の時に高さがずれる

アンカーリンクを設置している場合、遅延読み込みの画像の置き換えが追いつかず、高さがズレてしまうといったことが起こります。

これを解決する方法があります。

data-widthとdata-heightで画像のサイズを指定

読み込む画像のサイズを指定します。なぜdata属性での指定なのかは以下に書いてあるスクリプトの処理でwidthとheightを出力するためです。

<img src="data:image/gif;base64,R0lGODlhAQABAGAAACH5BAEKAP8ALAAAAAABAAEAAAgEAP8FBAA7" data-src="imageurl.jpg" data-width="120" data-width="50" class="lazyload">

スクリプトでwidthとheightを出力

data属性で指定しているものから要素の親の幅を計算して、widthとheightを出力します。The Okura TOKYOのサイトでも同じ手法を使っています。

$(function() {
    function loadImageHandler() {
     $('img[data-src]').each(function() {
      var parentwidth = $(this).parent().width();
      var width = $(this).attr('data-width');
      var height = $(this).attr('data-height');
      height = (parentwidth/width*height);
      width = parentwidth;
      $(this).attr({width: width})
      $(this).attr({height: height})
      $(this).on("load", function() {
       $(this).removeAttr("height")
       $(this).attr({ width: "100%" })
      });
     });
    }
    loadImageHandler();
    $(window).on('resize', loadImageHandler);
    function loadImageHandlerWrap() {
     $('img[data-src]').each(function() {
      $(this).wrap('<span class="lazyload__wrap" />');
     });
    }
    loadImageHandlerWrap();
    $(document).on('lazybeforeunveil lazyloaded', function(e){
     $(e.target).closest('.lazyload__wrap').attr('data-loaded', 'true');
    });
});

画像+テキストの2カラムで配置する場合は、画像をdivなどで囲って、幅の指定が必要になります。またimgタグにheight: autoの指定があると高さの取得がうまくいかないので、指定がある場合は外す必要があります。

lazysizesの拡張プラグインで指定したアスペクト比でダミー画像の高さを保ってくれるlazysizes aspectratio extensionがありますが、高さの取得がうまくいかない場合があり使えませんでした。

今のところ今回紹介した手法が問題ないかと思います。


サポートは今後のインプット・アウトプットのために使ってまた皆さんに還元します。