JavaScriptでローディング画面を作成する方法(画像を監視)

様々なサイトで実装されているローディング画面を実装したいと思ったことはありませんか?
この記事ではJavaScriptを使用してローディング画面を実装する方法をご紹介します。

ローディング画面を実装するメリット

  • ページを読み込んだときの表示の崩れがなくなる
  • ちゃんとページを読み込んでいることが伝わる
  • アニメーションを加えることで飽きさせず離脱率を下げる

上記のようなメリットがありますが、ここでの一番のメリットはやはり離脱率を下げれることかと思います。

一般的にはページ読み込み時間が3秒を超えると離脱率が高くなります。
しかし、ローディング画面を実装することで一部では離脱率が下がったという調査結果も出てきます。

JavaScriptでローディング画面を作成する方法

それではローディング画面を実装していきたいと思います。
まずはデモを用意しましたのでご確認下さい。

ローディングデモ:https://hirakublog.com/demo/page-loading

HTMLを記述

以下のHTMLをbody内のどこでもいいのでコピペして下さい。

<div class="js-loader">
  <div class="js-loader-progress">
    <div class="js-loader-progress-bar"></div>
    <div class="js-loader-progress-number"></div>
  </div>
</div>

CSS(scss)記述

以下のCSSはデモと同じものです。

.js-loader {
  position: fixed;
  width: 100%;
  height: 100%;
  top: 0;
  left: 0;
  visibility: visible;
  opacity: 1;
  background: #fff;
  transition: opacity .8s, visibility .8s;
  z-index: 10000;
  .is-loaded & {
    visibility: hidden;
    opacity: 0;
  }
}

.js-loader-progress {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  margin: auto;
  width: 100%;
  height: 1px;
  .is-loaded & {
    visibility: hidden;
    opacity: 0;
  }
}
.js-loader-progress-bar {
  background: #000;
  height: 100%;
  width: 0;
  transition: width .4s;
}
.js-loader-progress-number {
  text-align: center;
  font-size: 10px;
  width: 100%;
  margin-top: 10px;
}

JavaScriptを記述

今回のメインであるJavaScriptです。
実装するローディングは画像の読み込みを監視するものです。

画像が読み込まれていないとページが崩れる原因になるからです。

今回ローディングを実装する趣旨は読み込み時にが崩れないようにするです。

画像の読み込みを監視するimagesLoadedをインストール

画像の読み込みを監視にはimagesLoadedというプラグインを利用します。

imagesLoaded:https://imagesloaded.desandro.com/

読み込み方法は以下2種類を紹介します。

scriptタグ(CDN)で読み込む場合
<script src="https://unpkg.com/imagesloaded@4/imagesloaded.pkgd.min.js"></script>
NPMで読み込む場合
npm install imagesloaded
const imagesLoaded = require('imagesloaded');

ローディング用JS

以下のJavaScriptをコピペして下さい。それだけで動きます。

const progressBar = document.querySelector('.js-loader-progress-bar')
const progressNumber = document.querySelector('.js-loader-progress-number')

const imgLoad = imagesLoaded('body');//body内の画像を監視
const imgTotal = imgLoad.images.length;//画像の総数を取得

let imgLoaded = 0;//ロードした画像カウント
let progressSpeed = 8;//プログレスバーの進むスピード 大きいほど速くなる
let progressCount = 0;//ローディングの進捗状況 0〜100
let progressResult = 0;//ローディングの進捗状況 0〜100

//読み込み状況をアップデート
let progressInit = setInterval(function () {
  updateProgress();
}, 25);

//画像を一つロードするたびにimgLoadedのカウントをアップ
imgLoad.on('progress', function (instance, image) {
  imgLoaded++
})

//読み込み状況アップデート関数
function updateProgress() {

  //ローディング演出用の計算
  progressCount += (imgLoaded / imgTotal) * progressSpeed;

  if(progressCount >= 100 && imgTotal > imgLoaded) {
    //カウントは100以上だが画像の読み込みが終わってない
    progressResult = 99;
  } else if(progressCount > 99.9) {
    //カウントが100以上になった
    progressResult = 100;
  } else {
    //現在のカウント
    progressResult = progressCount;
  }

  //ローディング進捗状況をプログレスバーと数字で表示
  progressBar.style.width = progressResult + '%';
  progressNumber.innerText = Math.floor(progressResult);

  //ローディング完了後 0.8秒待ってページを表示
  if (progressResult >= 100 && imgTotal == imgLoaded) {
    clearInterval(progressInit);
    setTimeout(function () {
      document.querySelector('body').classList.add('is-loaded');
    }, 800);
  }
}

スクリプトは細かく解説はしませんがコメントを記述しています。

progressCountはただのローディングバーの演出です。
始まりが遅くその後加速するだけです。こうしたほうがローディングっぽく見えるからです。

しかし、本当に読み込みが完了してない場合は99で止まります。読み込み完了後100になります。

最後に

ローディング画面は正直好き嫌いが分かれるかなと思います。
僕はこの記事を書いておきながら言うのもなんですが、ローディング画面を実装することはあまりないです。

しかし、ローディング画面があるサイトを見ると読み込み完了まで待ってみようかなという気にはなります。
全体的に画像の多いサイト、デザインを重視したいサイトなどに実装するのがいいのではないでしょうか。