Webページ読み込み時にローディングアニメーションを実装する方法



ホームページやブログなどのWebサイトにアクセスした際に、Webページのリソース(画像や関連ファイル)が完全に読み込まれる前にページを表示しようとすると、レイアウトを含む表示崩れの状態が見えてしまったり、アクセス時に一番最初に見えるファーストビューに関連するものが遅いと、何も表示されない状態が長く続くこともあります。

綺麗に表示されるまでの待ち時間によってユーザーはストレスを感じてしまいますが、ローディングアニメーションを実装することで、ユーザーのストレスを軽減させたり、実装するアニメーション次第では待ち時間を楽しませることもできるので非常に効果的です。

1秒未満で表示されるような爆速ページでは、ローディングアニメーションは必要ないと思いますが、1つのパフォーマンスやデザインとして考えている場合は、ローディングアニメーションを数秒だけ実装するのもいいでしょう。

ここでは、Webページのリソースが完全に読み込まれるまでのローディングアニメーションと、JavaScriptを使って完全に読み込まれたタイミングでコンテンツを表示する方法をご紹介します。

ローディングアニメーションの実装


サンプルとして、よくある円の回転アニメーションを実装してみます。
まずは以下のように、ローディングを表現するためのHTMLを構築します。
body要素内の最初(一番上)に記述します。

HTML

<div id="loading">
  <div class="load">
    <div></div>
    <div></div>
  </div>
  <p class="loadText">Now Loading...</p>
</div>



ローディング用のブロックに、回転アニメーションを実装する要素のほか、「Now Loading」のテキストも用意してみました。

続いてはCSS。

ローディングの要素であるid「loading」に対し、positionプロパティをfixedとして幅と高さを画面全体に。
z-indexプロパティを記述しないことで初期値はautoとなり、基準となる0の値を意味しますので、ローディング要素の重ね順は一番上となります。
そして、CSSクラス「load」の要素にて、keyframesでアニメーションを定義してローディングを実装します。

CSS

#loading {
  position: fixed;
  width: 100%;
  height: 100%;
  background: #fff;
}

#loading.loadEnd {
  animation: fadeOut 0.5s ease forwards;
}

@keyframes fadeOut {
  0%{
    opacity: 1;
  }
  100%{
    opacity: 0;
  }
}

.load {
  position: fixed;
  top: 50%;
  left: 50%;
  transform: translateY(-50%) translateX(-50%);
  width: 40px;
  height: 40px;
  background: #eee;
  border-radius: 50%;
}

.load:after {
  content: "";
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translateY(-50%) translateX(-50%);
  width: 32px;
  height: 32px;
  background: #fff;
  border-radius: 50%;
}

.load div {
  width: 40px;
  height: 20px;
  border-radius: 20px 20px 0 0;
}

.load div:first-child {
  background: #f70;
  transform-origin: 20px 20px;
  transform: rotate(0deg);
  animation: loading 0.5s linear 0s infinite;
}

@keyframes loading {
  0% {
    transform: rotate(0deg);
  }
  100% {
    transform: rotate(360deg);
  }
}

.loadText {
  position: fixed;
  top: 50%;
  left: 50%;
  transform: translateY(100%) translateX(-50%);
  font-size: 1.25rem;
}



id「loading」のセレクタに指定しているCSSクラス「loadEnd」は、この後のJavaScriptでページ読み込み後にクラスを付与させます。ページ読み込み後にローディングアニメーションを終了させるため、keyframesでfadeOutのアニメーションを定義してセレクタに指定しておきます。

ページ読み込み後の処理


ページ読み込み後の処理は、JavaScriptで実装していきます。
ページの読み込みが完全に終了したかは、addEventListener()メソッドloadイベントのイベントリスナーを設定します。
loadイベントは、リソースが完全に読み込まれたときに発行されます。

JavaScript

window.addEventListener("load", (event) => {
  function fadeOut() {
    const elements = document.querySelector('#loading');
    elements.classList.add("loadEnd");
  }
  setTimeout(fadeOut, 1000);
});



fadeOutの関数を定義し、一定時間後に実行させるsetTimeout()メソッドで、fadeOutの関数を1000ミリ秒(1秒)後に実装するようにしています。
どれだけ爆速なWebページでも、読み込み時間+1秒はCSSのローディングアニメーションが実装されます。
例えば、ページの読み込みが2秒かかる場合は、読み込み後のsetTimeout()メソッドの1秒と、合わせて3秒後にWebページが表示されることになります。

ページ読み込み後になるべく早くWebページを表示させたいのであれば、setTimeoutの時間を500ミリ秒(0.5秒)後とさらに短い時間に設定するといいでしょう。
または即時に実装する場合、setTimeoutは使わなくてOKです。

JavaScript

window.addEventListener("load", (event) => {
  function fadeOut() {
    const elements = document.querySelector('#loading');
    elements.classList.add("loadEnd");
  }
  fadeOut();
});



リソースの読み込みが3秒、4秒と、Webページの表示がそこまで速くないとわかっている場合は、即時に処理をしてもいいでしょう。

ローディングアニメーション終了後に要素も一緒に削除する場合は、remove()メソッドを使って要素を削除します。
また削除するタイミングは、CSSのアニメーションで定義しているフェードアウト処理の時間(1000ミリ秒)に合わせて、フェードアウトのアニメーションが終了するタイミングとなるようにsetTimeout()メソッドで実行します。

JavaScript

window.addEventListener("load", (event) => {
  function fadeOut() {
    const elements = document.querySelector('#loading');
    elements.classList.add("loadEnd");
    setTimeout(function(){
      elements.remove();
    }, 1000);
  }
  setTimeout(fadeOut, 1000);
});



CSSのopacityプロパティで透過させて非表示としていますが、SEOの観点から非表示に隠しておく要素があると悪影響を与えるかもしれないと心配になる方は、要素を削除しておくといいでしょう。
テキストを含むコンテンツではないので、私は大丈夫だと思いますが。

jQueryの場合


jQueryで記述する場合は、on()メソッドを使いloadイベントで関数を実行します。
jQueryではfadeOut()メソッドがありますので、セレクタに対してfadeOut()メソッドを実装すればOKです。
この時、セレクタに対するクラス「loadEnd」の付与や、CSSのフェードアウトのアニメーションは必要ありません。

jQuery

$(window).on('load',function(){
  setTimeout(function(){
    $('#loading').fadeOut();
  }, 1000);
});



また、ローディングアニメーション終了後に要素も一緒に削除する場合は、fadeOut()メソッドに対してコールバック関数を実装し、フェードアウト後にremove()メソッドで要素を削除します。

jQuery

$(window).on('load',function(){
  setTimeout(function(){
    $('#loading').fadeOut(1000, function(){
      $(this).remove()
    });
  }, 1000);
});



fadeOut()メソッドの引数に指定している変化の時間は1000ミリ秒(1秒)としていますが、時間の調整が必要なければ「1000,」は削除しても構いません。

以下、JavaScriptを使ったページの読み込みに合わせたローディングアニメーションの実装になります。
動画(2分12秒)

まとめ


ページのリソースがすべて読み込まれるタイミングは、JavaScriptのイベントリスナーを使用して、loadイベントでリソースが完全に読み込まれたときに処理できます。
そのタイミングで要素にクラスなどを付与して、CSSのアニメーションを使いながら、ローディングアニメーションを終了させると同時にページコンテンツを表示させます。

ローディングアニメーションの要素は一番上に画面全体に表示されるようにして、ローディングアニメーションはCSSやJavaScriptで実装するか、またはGIFアニメーションやアニメーションPNG等を使うかはお好みの方法で実装していただければと思います。