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!

ⓘ I have included a zip file with all the source code at the start of this tutorial, so you don’t have to copy-paste everything… Or if you just want to dive straight in.

 

 

TABLE OF CONTENTS

Download & Notes Loading Order AJAX Load
Useful Bits & Links The End

 

DOWNLOAD & NOTES

Firstly, here is the download link to the example code as promised.

 

QUICK NOTES

If you spot a bug, feel free to comment below. I try to answer short questions too, but it is one person versus the entire world… If you need answers urgently, please check out my list of websites to get help with programming.

 

EXAMPLE CODE DOWNLOAD

Click here to download all the example source code, I have released it under the MIT license, so feel free to build on top of it or use it in your own project.

 

 

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
<head>
  <!-- (A) LOADING SPINNER -->
  <link rel="stylesheet" href="1b-load-spinner.css">
</head>
<body>
  <!-- (B) THIS COMES FIRST -->
  <div id="loading"></div>
 
  <!-- (C) REST OF THE PAGE -->
  <p>YOUR CONTENT HERE</p>
 
  <!-- (D) LOAD JS/CSS LAST -->
  <script src="1c-loader.js"></script>
  <script>
  window.onload = () => {
    // JUST DEFINE EMPTY ARRAY [] IF NO CSS/JS TO LOAD
    loader(
      ["my.css"],
      ["my.js", "https://cdnjs.cloudflare.com/ajax/libs/WHATEVER/"]
    );
  };
  </script>
</body>

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

  • (A & B) 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.
  • (C) Your “regular HTML content” follows after the loading spinner.
  • (D) 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-loader.js
function loader (css, js) {
  // (A) TOTAL NUMBER OF SCRIPTS
  var total = css.length + js.length,
  now = 0, s;
 
  // (B) READY?
  var ready = () => {
    now++;
    if (now==total) { document.getElementById("loading").remove(); }
  };
 
  // (C) INSERT <LINK> INTO <HEAD>
  css.forEach((url, i) => {
    s = document.createElement("link");
    s.rel = "stylesheet";
    s.href = url;
    s.onload = ready; s.onerror = ready;
    document.head.appendChild(s);
  });
 
  // (D) INSERT <SCRIPT> INTO <HEAD>
  js.forEach((url, i) => {
    s = document.createElement("script");
    s.src = url;
    s.onload = ready; s.onerror = ready;
    document.head.appendChild(s);
  });
}

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
<head>
  <!-- (A) CSS STYLES -->
  <link rel="stylesheet" href="2b-styles.css">
 
  <!-- (B) SCRIPTS -->
  <script src="2c-loader.js"></script>
  <script>
  window.onload = () => { loader("2d-content.html"); };
  </script>
</head>
<body>
  <!-- (C) HTML PAGE AS USUAL -->
  <header>Header</header>
  <main id="main"></main>
  <footer>Footer</footer>
 
  <!-- (D) LOADING SPINNER -->
  <div id="loading"></div>
</body>

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

  • (A & B) Load the CSS/JS as usual.
  • (C) The usual HTML page structure, but take note – The <main id="main"> section is empty.
  • (D) The fullscreen loading spinner.

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.

 

2D) DUMMY CONTENT

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

Just some dummy content.

 

USEFUL 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.

 

LOADING SCREENS ARE NOT 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!

Leave a Comment

Your email address will not be published.