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がありますが、高さの取得がうまくいかない場合があり使えませんでした。
今のところ今回紹介した手法が問題ないかと思います。
サポートは今後のインプット・アウトプットのために使ってまた皆さんに還元します。