In this post we will create a indicator displaying the percentage of website loaded. This indicators are used in websites with large web page size to display the progress of webpage. Youtube too display a indicator on top. I was inspired to write this post after looking at a awesome javascript library pace.js which does the same.
Let’s see some concepts which are important to understand before building a indicator for page load.
document.readyState Property
document.readyState property returns loading status of current page. This property can have one of these four values:
- uninitialized – not yet started loading the page
- loading – page has started loading
- interactive – Page has loaded but resources like images, stylesheets and frames(resources retrieved asynchronously) are not yet loaded. This is same as DOMContentLoaded event of document object.
- complete – Page is fully loaded. All resources are loaded. Its same as window.onload Event. window.onload is same as the onload property of body tag. Its triggered after all resources inside the window has been completely loaded. Remember that HTML tags don’t have a onload event, its the body tag onload event that triggers after all HTML code and external resources has been loaded.
readystatechange DOM Event
readystatechange event is triggered whenever there is a change in value of readyState property.
Calculating percentage of page load
There is no way of finding exact percentage of page loaded. We just need to create a illusion of percentage of page loaded. This can be done by starting the increment in percentage at very fast rate and then slowing down gradually.
Implementation of page loader
I created a infinitely loading page so that we can see the way the percentage changes. At 99% we stop and wait till loading is finished to make it 100%. You can try this exact code in any webpage of your wish.
This is the code present in our live preview.
index.php
<?php
set_time_limit(0);
?>
<!doctype html>
<html>
<head>
<script type="text/javascript" src="/blogpageloader_percentage.js"></script>
<link rel="stylesheet" href="pageloader_percentage.css">
</head>
<body>
<?php
while(True)
{
?>
<p>Sending Data</p>
<?php
ob_flush();
flush();
sleep(3);
}
?>
</body>
</html>
pageloader_percentage.css
#pageLoader
{
font-size:70px;
}
pageloader_percentage.js
var pageStatus = null;
var progress = null;
var animationInterval = 33;
window.document.addEventListener( "readystatechange", function () {
if ( document.readyState == "complete" ) {
pageStatus = "complete";
}
}, false );
function updateProgress () {
if ( pageStatus == "complete" ) {
document.getElementById( "pageLoader" ).innerHTML = 100;
setTimeout( function () {
document.getElementById( "pageLoader" ).style.display = "none";
}, 700 );
}
else {
if ( progress == null ) {
progress = 1;
}
progress = progress + 1;
if ( progress >= 0 && progress <= 30 ) {
animationInterval += 1;
document.getElementById( "pageLoader" ).innerHTML = progress;
} else if ( progress > 30 && progress <= 60 ) {
animationInterval += 2;
document.getElementById( "pageLoader" ).innerHTML = progress;
} else if ( progress > 60 && progress <= 80 ) {
animationInterval += 3;
document.getElementById( "pageLoader" ).innerHTML = progress;
} else if ( progress > 80 && progress <= 90 ) {
animationInterval += 4;
document.getElementById( "pageLoader" ).innerHTML = progress;
} else if ( progress > 90 && progress <= 95 ) {
animationInterval += 80;
document.getElementById( "pageLoader" ).innerHTML = progress;
} else if ( progress > 95 && progress <= 99 ) {
animationInterval += 150;
document.getElementById( "pageLoader" ).innerHTML = progress;
} else if ( progress >= 100 ) {
document.getElementById( "pageLoader" ).innerHTML = 99;
}
setTimeout( updateProgress, animationInterval );
}
}
var intervalObject_1 = setInterval( function () {
var element = document.querySelector( "body" ); if ( element != undefined ) {
clearInterval( intervalObject_1 );
element.innerHTML += "0";
updateProgress();
}
}, 50 );
Remember to insert the js and css file just after the head tag starts. So that they can start operating as soon as possible.
First we continuously check at 50ms interval for the body tag to appear in DOM. Once it appears we insert our loader markup into the body. And then start updating the percentage regularly using setTimeout function. Depending on the current percentage of page loaded we change the speed at which setTimeout calls update function. So we slow down gradually. When page is finished loading we display 100% and then after 700ms we remove the loader. Therefore this illusion works very well.
All website you have seen till now using a page loader in percentage just make illusions.
Similarly you can just create a animated loader instead of showing the percentage of page loaded. That would be even easier as you will only have to catch the body tag and readystatechange event.
Pace.js as a rescue
If you don’t want to write a loader yourself. Than you can use Pace javascript library for implementing a loader in your website. It also uses the above technique of illusion for displaying the percentage of page loaded.
Conclusion
Its always better to just display a animated GIF or CSS animation instead of showing percentage as you don’t know the users bandwidth speed and website processing time. You can customize the setTimeout callback time further to make it behave more natural.