Problem – Slow loading pages are frustrating, for web users and developers too. Of course there are many possible tweaks you can use to speed them up, but sometimes you cannot optimize a page any further.

  • UPDATED 2009-10-11

Solution – If you can’t beat them, join them. You can show a progress indicator to let your web users know that your server is thinking hard the answer to their request, but how do you do that?

Requirement 1 – You cannot put the progress indicator on the leaving page, because you don’t want to modify every single reference to a slow page. It doesn’t make sense either: a slow page is slow by itself! You really don’t need that coupling.

Requirement 2 – You cannot put the progress indicator on the landing page, the slow one, because the browser needs it before the slow page has arrived. If they arrive together, the progress indicator is useless!

There is a good article about this issue but it fails at implementing the first requirement. Anyway that was the idea I worked on when starting this project.

Here is the waiting page that get’s loaded while loading the slow page. For browsers other than IE, the trick is to change the document.location.href property after loading the progress indicator image. In IE we change the document.location.href and then add the image.

I used jQuery to make it simple.

waiting.php

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "DTD/xhtml1-transitional.dtd">

<html xml:lang="en" lang="en" xmlns="http://www.w3.org/1999/xhtml"><head>

<title>Loading Page...</title>

<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3/jquery.min.js"></script>
<script type="text/javascript">
jQuery( function( $ ) {
	function redirect() {
		$('form').submit();
	}
	
	if($.browser.msie) {
		redirect();
		$('img').appendTo('body').attr('src', 'loading-page.gif');
	} else {
		$('#loading').bind('load', function() {
	        redirect();
	    }).attr('src', 'loading-page.gif');
	}
} );
</script>

</head><body>

<h1>Loading Page...</h1>
<img id="loading" />
<form method="<?php echo $method ?>" action="<?php echo $url ?>">
 <input type="hidden" name="waiting" value="<?php echo $waiting ?>" />
</form>

</body></html>

And here is the slow page.

slow-page.php

<?php

if ( ! isset($_REQUEST['waiting']) ) {
    $url = htmlspecialchars( $_SERVER['REQUEST_URI'] );
	$method = $_SERVER['REQUEST_METHOD'];
	$waiting = time();
	include "waiting.php";
    return;
}

sleep(10); //simulate a slow task

?>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "DTD/xhtml1-transitional.dtd">

<html xml:lang="en" lang="en" xmlns="http://www.w3.org/1999/xhtml"><head>
 <title>Slow Page</title>
</head><body>
 <h1>Hello World!</h1>
</body></html>

You can test it here.