2 Ways To Show Loading Spinner Until Page Loads

Welcome to a quick tutorial on how to show a loading spinner until the page is fully loaded. This is a seemingly easy thing to do until you get your hands dirty… Some other tutorials online got me to facepalm with their “solution” involving the use of third-party libraries.

No, we don’t need to load an entire library to show a “now loading” screen. In actual fact, it only involves dealing with the loading order of your scripts – Read on for the examples!

 

 

TABLE OF CONTENTS

 

METHOD 1) LOADING ORDER

All right, let us now get into the first method – Simply reordering your scripts and page structure.

 

1A) THE HTML

1a-load-order.html
<!DOCTYPE html>
<html>
  <head>
    <!-- (A1) LOADING SPINNER -->
    <link rel="stylesheet" href="1b-load-spinner.css">
    <script src="1c-load-spinner.js"></script>
  </head>
  <body>
    <!-- (A2) LOADING SPINNER -->
    <div id="loading"></div>
 
    <!-- (B) REST OF THE PAGE -->
    <p>YOUR CONTENT HERE</p>
 
    <!-- (C) LOAD JS/CSS LAST -->
    <script>
    // JUST RUN LOADER() IF NO SCRIPTS TO LOAD
    window.addEventListener("DOMContentLoaded", () => loader([
      "my.CSS", "my.js", "https://cdnjs.cloudflare.com/ajax/libs/WHATEVER.JS"
    ]));
    </script>
  </body>
</html>

Before we get into the script, here’s an important recap – HTML pages load from top to bottom, left to right.

  1. So naturally, we have to prioritize the loading spinner right at the top; The spinner is the first thing that shows while the rest loads.
  2. Your “regular HTML content” follows after the loading spinner.
  3. Leave the CSS and Javascript to the end.

 

 

1B) FULLSCREEN SPINNER CSS

1b-load-spinner.css
#loading {
  /* (A1) COVER FULL PAGE */
  position: fixed;
  top: 0; left: 0; z-index: 999;
  width: 100vw; height: 100vh;
 
  /* (A2) SPINNER IMAGE */
  background-color: black;
  background-image: url("ajax-loader.gif");
  background-position: center;
  background-repeat: no-repeat;
}

Nothing much here. This bit of CSS sets <div id="loading"> to cover the entire screen and adds a loading spinner.

 

 

1C) JAVASCRIPT TO LOAD CSS/JS

1c-load-spinner.js
function loader (all) {
  // (A) ALL LOADED - REMOVE SPINNER
  var total = 0, loaded = 0, s,
  ready = () => {
    loaded++;
    if (loaded>=total) { document.getElementById("loading").remove(); }
  };
 
  // (B) CREATE <LINK><SCRIPT>
  if (Array.isArray(all)) {
    total = all.length;
    all.forEach(url => {
      // (B1) CSS FILE - <LINK>
      if (url.toLowerCase().includes(".css")) {
        s = document.createElement("link");
        s.rel = "stylesheet";
        s.href = url;
        s.onload = ready; s.onerror = ready;
      }
 
      // (B2) JS FILE - <SCRIPT ASYNC>
      else {
        s = document.createElement("script");
        s.async = true;
        s.src = url;
        s.onload = ready; s.onerror = ready;
      }
      document.head.appendChild(s);
    });
  }
 
  // (C) JUST START IF NO SCRIPTS TO LOAD
  else { ready(); }
}

Yes, we can just put <script> <link rel="stylesheet"> <style> at the bottom of the page. But there is also a problem – We cannot track their loading progress without the use of Javascript. Thus this snippet once again, to remove the loading spinner when all the scripts are fully loaded.

 

 

METHOD 2) AJAX LOAD

Next, we have an alternative method – Using AJAX to load the page.

 

2A) THE HTML

2a-ajax-load.html
<!DOCTYPE html>
<html>
  <head>
    <!-- (A) CSS & SCRIPTS -->
    <link rel="stylesheet" href="2b-styles.css">
    <script src="2c-loader.js"></script>
    <script>
    window.onload = () => loader("2d-content.html");
    </script>
  </head>
  <body>
    <!-- (B) LOADING SPINNER -->
    <div id="loading" class="load"></div>
 
    <!-- (C) HTML PAGE AS USUAL -->
    <header>Header</header>
    <main id="main"></main>
    <footer>Footer</footer>
  </body>
</html>

Yes, this is more like a “normal HTML page”.

  1. Load the CSS/JS as usual.
  2. The fullscreen loading spinner. As usual, this is right at the top – So that it shows while the rest of the page is loading.
  3. The usual HTML page structure, but take note – The <main id="main"> section is empty.

In other words, we load an empty page template first. Then use AJAX to load the content into <main id="main">. For the uninitiated, this is the principle behind a “one-page app”. The user does not have to reload the entire page, only the content is dynamically refreshed via AJAX.

 

2B) FULLSCREEN SPINNER CSS

2b-styles.css
#loading {
  /* (A1) COVER FULL PAGE */
  position: fixed;
  top: 0; left: 0; z-index: 999;
  width: 100vw; height: 100vh;
 
  /* (A2) SPINNER IMAGE */
  background-color: rgba(0, 0, 0, 0.5);
  background-image: url("ajax-loader.gif");
  background-position: center;
  background-repeat: no-repeat;
 
  /* (A3) HIDDEN BY DEFAULT */
  display: none;
}
 
/* (A4) SHOW LOADING */
#loading.load { display: block; }

Look no further, this is the same. Except that the spinner is hidden by default, we use the .load to toggle the show/hide.

 

 

2C) AJAX LOAD CONTENT

2c-loader.js
function loader (url, loaded) {
  // (A) GET HTML ELEMENTS
  var main = document.getElementById("main"),
      loading = document.getElementById("loading");
 
  // (B) LOADING SPINNER
  loading.classList.add("load");
 
  // (C) AJAX LOAD PAGE
  fetch(url)
  .then(res => res.text())
  .then(txt => {
    main.innerHTML = txt;
    if (typeof loaded == "function") { loaded(); }
  })
  .finally(() => loading.classList.remove("load"));
}

Well, we are just using AJAX fetch to load content into <main>. Of course, also show the fullscreen loading spinner while it loads.

P.S. You can call loader("ANOTHER-PAGE") to replace the current page at any time. As above, this is how single page apps work.

 

2D) DUMMY CONTENT

2d-content.html
<h1>Hello World</h1>
<p>It works!</p>

Just some dummy content.

 

DOWNLOAD & NOTES

Here is the download link to the example code, so you don’t have to copy-paste everything.

 

SORRY FOR THE ADS...

But someone has to pay the bills, and sponsors are paying for it. I insist on not turning Code Boxx into a "paid scripts" business, and I don't "block people with Adblock". Every little bit of support helps.

Buy Me A Coffee Code Boxx eBooks

 

EXAMPLE CODE DOWNLOAD

Click here for the source code on GitHub gist, just click on “download zip” or do a git clone. I have released it under the MIT license, so feel free to build on top of it or use it in your own project.

 

EXTRA BITS & LINKS

That’s all for the tutorial, and here is a small section on some extras and links that may be useful to you.

 

A LOADING SCREEN IS NO GOOD

Loading screens are cool, that’s what I thought as a newbie as well. But in this age of “I want information fast” (how many of you guys actually read everything without “TLDR”), people don’t have much patience to stare at a loading screen.

So spend more effort simplifying your site, not inflating it with all the bells and whistles. It’s counterproductive these days; If you can serve a simple page in 3 seconds, please do so. Leave the loading screen to “complex web apps”.

 

COMPATIBILITY CHECKS

The examples work on all modern “Grade A” browsers.

 

LINKS & REFERENCES

 

THE END

Thank you for reading, and we have come to the end. I hope that it has helped you to better understand, and if you want to share anything with this guide, please feel free to comment below. Good luck and happy coding!

2 thoughts on “2 Ways To Show Loading Spinner Until Page Loads”

Comments are closed.