How to supercharge your site’s speed with AJAX and jQuery

In this tutorial we’re going to look at how to speed up the user experience on small static sites using a few different methods. (A static site is one which doesn’t have any renewing content, so no blog posts or photo streams etc.)

The way we’re going to be doing this is by taking out page reloads. So simply put, when the user uses some navigation links, only the main content of the page changes and it doesn’t make the browser reload the page.

We will be achieving this effect in two different ways, the first only uses jQuery, and the other uses AJAX and some PHP. They both have their pros and cons, which we’ll look at as well. Take a look at the demo to see what we’re trying to achieve and let’s start with the first (and simpler) jQuery method.

 

Achieving the effect with jQuery

First we will look at the setup for the page. The HTML is very simple but has a few important parts, “the essentials” as it were. We need some navigation links which have a specific hash href (which we’ll explain in a minute) and a specified content area which you would already have on any other site anyway. So let’s first see what is in our index.html file:

<body>
<header>
    <h1>Speed Up Static Sites with jQuery</h1>
    <nav>
        <ul>
            <li><a href="#page1" class="active" id="page1-link">Page 1</a></li>
            <li><a href="#page2" id="page2-link">Page 2</a></li>
            <li><a href="#page3" id="page3-link">Page 3</a></li>
            <li><a href="#page4" id="page4-link">Page 4</a></li>
        </ul>
    </nav>
</header>
<div id="main-content">
    <section id="page1">
        <h2>First Page Title</h2>
        <p>First page content.</p>
    </section>
    <section id="page2">
        <h2>Look, no page load!</h2>
        <p>Second page content.</p>
    </section>
    <section id="page3">
        <h2>Ooh fade!</h2>
        <p>Third page content.</p>
    </section>
    <section id="page4">
        <h2>Fourth Page Title</h2>
        <p>Fourth page content.</p>
    </section>
</div> <!-- end #main-content -->
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
<script type="text/javascript" src="custom.js"></script>
</body>

So to recap the important parts of what needs to go into the markup: we have our navigation in which each link has an href of the corresponding DIV. So the link to “Page 2″ has a href=”#page2″ (which is the id of the <section> element further down). So with this first method as you can see we have a div of #main-content surrounding our sections, and then each page content one after the other in their own separate ‘section’ element. We also call jQuery and our own custom.js javascript file in which the actual functionality of the site will be made.

But before we get to that we need to add one line to our CSS, there’s no need to go over the whole CSS file for this example as it’s all only for looks, which will change with whatever project you’re working on. However, with this first method there’s one line that’s essential and that’s:

#page2, #page3, #page4 {
display: none;
}

This hides all the ‘pages’ except the first one. So the page appears normally on first load.

The JavaScript

So now to explain what we need to achieve via jQuery. In our custom.js file, we need to target when the user clicks on a navigation link. Retrieve its href link and find the ‘section’ with that same ID, then hide everything in the #main-content div and fade in the new section. This is what it looks like:

$(function() {
    $('header nav a').click(function() {
        var $linkClicked = $(this).attr('href');
        document.location.hash = $linkClicked;
        if (!$(this).hasClass("active")) {
            $("header nav a").removeClass("active");
            $(this).addClass("active");
            $('#main-content section').hide();
            $($linkClicked).fadeIn();
            return false;
        }
        else {
            return false;
        }
    });
    var hash = window.location.hash;
    hash = hash.replace(/^#/, '');
    switch (hash) {
        case 'page2' :
            $("#" + hash + "-link").trigger("click");
            break;
        case 'page3' :
            $("#" + hash + "-link").trigger("click");
            break;
        case 'page4' :
            $("#" + hash + "-link").trigger("click");
            break;
    }
});

This code is split into two sections, the first achieves what we just talked about. It has a click function on the header nav links. It then puts the ‘#page1, #page2′ etc into a variable named $linkClicked. We then update the browser’s URL to have that same hash name. Then we have an if statement making sure the link we’re clicking is not the current tab, if it is then do nothing, but if not hide all current content and unhide the div with an ID of $linkClicked. Simple as that!

The second section checks if the url has a hash link on the end of it, if it does, it finds a corresponding link on the page with the same value (that’s why the links have specific IDs in the markup) and then it triggers that link (it clicks on it). What this does, is means the user can reload a page after having navigated to a ‘page’ and the refresh will send the user back there instead of just back to the first page, which can often be a problem with this sort of system.

So that’s the end of the first method, this results in a working static site that has instantaneous content swapping, and no page reloads. The only drawback to this method is the fact that all the content is called on the initial load, as it’s all there in the index file. This can start to be a problem with photos and extra content making the first site visit load a bit longer. So let’s look at another way to do this same effect which can eliminate that problem.

 

Using AJAX and PHP

To achieve this same effect but in a slightly different way, so that the initial load isn’t going to load all of our content and thus slow it down (defeating the point if the site has a lot of content) we will use a little PHP and AJAX. This means that the file structure for our project will change and look like this:

structure

So if you look, the index file is now a .php and not a .html. We also have an extra file named ‘load.php’ as well as a new folder/directory called pages in which there are four HTML pages. Now this means that if you’re working locally you need to set up a local development environment using something like MAMP (for Mac) or WAMP Server (for Windows). Or you can upload the whole folder onto a web server if you have access and edit on there, basically you’ll need an environment where the PHP will work.

The index.php has only changed one thing, but it’s important, we will now not load all the content in there, and simply call the initial content in with a PHP include. It now will look something like this:

<body>
<header>
    <h1>AJAX a Static Site</h1>
    <nav>
        <ul>
            <li><a href="#page1" class="active" id="page1-link">Page 1</a></li>
            <li><a href="#page2" id="page2-link">Page 2</a></li>
            <li><a href="#page3" id="page3-link">Page 3</a></li>
            <li><a href="#page4" id="page4-link">Page 4</a></li>
        </ul>
    </nav>
</header>
<div id="main-content">
<?php include('pages/page1.html'); ?>
</div> <!-- end #main-content -->
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
<script type="text/javascript" src="custom.js"></script>
</body>

So the line beginning <?php is calling in the first HTML file from our folder of pages and inserting in entirely into our #main-content DIV. The file called can contain whatever content you want to appear on the page.

Using $.ajax in the JavaScript

Let’s move onto the new JavaScript, it now looks slightly different, mainly we’re now using AJAX to fetch the new content from each HTML file when the user clicks on some corresponding navigation. Here’s the first function in the code (the second stays the same as before):

$(function() {
    $('header nav a').click(function() {
        var $linkClicked = $(this).attr('href');
        document.location.hash = $linkClicked;
        var $pageRoot = $linkClicked.replace('#page', '');
        if (!$(this).hasClass("active")) {
            $("header nav a").removeClass("active");
            $(this).addClass("active");
            $.ajax({
                type: "POST",
                url: "load.php",
                data: 'page='+$pageRoot,
                dataType: "html",
                success: function(msg){
                if(parseInt(msg)!=0)
                {
                    $('#main-content').html(msg);
                    $('#main-content section').hide().fadeIn();
                }
            }
        });
    }
    else {
        event.preventDefault();
    }
});

So let’s explain what’s going on. We’re adding one more variable, that’s $pageRoot. This is basically the actual number clicked (taking way the ‘#page’ part of the hash link and leaving the individual number). Then inside the same “if” statement as before we call ajax and use the other PHP file we mentioned earlier to parse the information given (which link has been clicked) and find the corresponding page. Then if it comes back with no error, we insert the new HTML from the file received into our #main-content DIV. Then just to stop it changing suddenly, we hide everything and then fade it in.

load.php

The contents of the new PHP file is short and sweet, it takes the page number that jQuery has sent it and looks to see if the corresponding HTML file exists. If it does it gets all the content and returns it to the AJAX function (which we showed a moment ago that we insert that content into the main DIV).

<?php
if(!$_POST['page']) die("0");
$page = (int)$_POST['page'];
if(file_exists('pages/page'.$page.'.html'))
echo file_get_contents('pages/page'.$page.'.html');
else echo 'There is no such page!';
?>

Following that the site should look however you want it to, but mostly work properly.

That’s it! The site now calls in the right corresponding HTML file each time the user clicks on a navigation link. It swaps out the content without making the page reload. And this way it still doesn’t have to call all the content on the initial page load! I hope you’ve managed to learn some useful method from this tutorial and that you can use it to improve some project in some way.

You can view the jQuery demo here, the PHP demo here, or download the source and take a closer look.

Have you used AJAX for loading content? Have you used a similar technique to speed up your site? Let us know your thoughts in the comments below.

Featured image/thumbnail, supercharged image via Shutterstock.

0 shares
  • Mike

    nice tutorial. Hows does this effect SEO with regards to the site structure and content?

  • Phil

    Agreed, Angular/Backbone/Ember all have greater scope. As long as there’s a no-js fallback.

  • http://timseverien.nl/ Tim Severien

    Supercharging a site and jQuery in one sentence… the irony!

    On a serious note…
    The HTML page may load fast, but what you’re really doing is just delaying. Now you have more HTTP calls and more JavaScript to get this thing going. It’s deceiving to call this a me5hod to decrease loading time. Let’s not forget about search engines too.

    Instead, good caching goes a long way. CSS, JavaScript, images and fonts are all static, so you can safely cache those on the client. Load once, be done with it. Whether you load content over AJAX or not.
    For dynamic pages, you can store stuff server-side. Database calls, the output buffer based on the URI or cache only parts of a page. You can make it as complex as you like and it’ll most likely be faster than fetching it all from the database. Heck, you could even cache the bytecode if you like. Caching is more than a couple HTTP headers.
    When you make changes to your content, just update the cache too and you’re set for the next flood without a performance hit.

    I truly think loading content with AJAX is not a legitimate solution to page performance. Search engines don’t handle JavaScript or AJAX well (whatever Google says), so you’re only creating a new problem. Splitting things may decrease the initial load, but will increase the final load time. Caching is win. Though server-side caching may cost a couple megabytes worth of disk space, the loading time will be sweet!

    • http://wtff.com/ 011011010010011101111010

      “Supercharging a site and jQuery in one sentence… the irony!”

      Then most of the websites, including industry leaders, are ironic …
      Excuse us, please )

  • CreativPixel

    In method one i suggest you hide the pages with CSS only if Js is active. So you have to build in a check and then apply the CSS, or just hide the pages with JS. Otherwise visitors without js won’t see 3 of your pages.

  • chronicler_Isiah

    Interesting but I’m not seeing how this fairly complex solution is actually speeding anything up. There is also the issue of the added http header requests that for me feel unwarranted for a static htm page.

    I think there are far more effective ways to speed page loading: compressing and concatenating multiple css and javascript files, properly optimising images, caching, gzipping, the correct placement of any scripts within the running order of htm code, not using too many @font-faces, not using affiliate ads with bloated or poor javascript/htm code etc etc.

  • someshl

    How to implement the same thing is WordPress