img や iframe のロードなんて待てない! JavaScript で お手軽遅延ロード(Lazy loading) を実装する方法

phi phi on javascript

このブログに Lazy loading を組み込んだので, 備忘録がてらエントリーにしてみました.

よく, src を data-src に置き換えておいて... みたいな手法がありますが, これだと既存のページもすべて手を加える必要があります.

今回は, 既存のページでもお手軽に Lazy loading にする方法を紹介します.

Lazy loading とは?

Web ページを開いた際, 大きな画像や iframe が含まれている場合,
表示が遅くなってしまうことが多々あると思います.

スクロールしないと見えない画像や, 埋め込んだ iframe のせいで ユーザーのレスポンスが大きく損なわれるのは悲しいですよね.

そういった時に使えるのが Lazy loading というテクニックです.

まぁその名の通り遅延読み込みのことで, 最初にダミーの url を差し込んでおいて, 後でスクロールしたり, ボタンを押したタイミングで本ちゃん url に差し替えるという手法です.

こうすることで, 必要なものを必要なタイミングでロードできるので, 画像や iframe がたくさんあるページでもスムーズに表示することができます.

メリット

  • ページ表示速度が上がる
  • 不要な通信を防ぐ

デメリット

  • キャプチャサービスなどを使った際に意図した表示にならないことがある

Runstant Demo

スクロールによる Lazy loading もあるのですが, 今回はクリックによる Lazy loading の実装方法について紹介します.

基本的にはロードのきっかけがクリックかスクロールかの違いで, 考え方は同じです.

とりあえず実装したデモを見てみて下さい. 枠をクリックすると正規の画像が表示されるのがわかるかと思います.

簡易 Lazy loading を実装しよう

たったこれだけです.

var images = Array.prototype.slice.call(document.images);

images.forEach(function(image) {  
  var src = image.getAttribute('src');
  image.removeAttribute('src');

  image.onclick = function() {
    image.src = src;
  };
});

これを script タグの中に書くだけで画像がすべて Lazy loading になります.

やっているのは

  • document.imagesimg タグをすべて取得
  • それを Array.prototype.slice.call() で配列化
  • forEach で回す
  • image 要素の src を取り出して削除
  • クリックしたら取り出しておいた src を再設定

って感じです.

注意点として, この処理は head タグではなく body タグの最後 に 書いて下さい.

ここではなく

<head>

  ...

  <script>
  // ここではなく
  var src = ...
  </script>
</head>  

ここ

<body>

  ...

  <script>
  // ここです!
  var src = ...
  </script>
</body>  

ここです!

また, document.images の部分を document.getElementsByTagName('iframe') とすれば iframe の Lazy loading になります.

Reference