DEV Community

Cover image for Building lightweight single page apps
Ilya Nevolin
Ilya Nevolin

Posted on

Building lightweight single page apps

My most recent project involved building a single page application. In this post I will share my strategy as well as some tips.

Codr didn't start off as a single page application. Each page was actually, like on any other regular website, just another page. But after speed tests and optimizing for offline usage, I had to adjust my strategy. I had to convert the individual pages into a single page app; to make it much faster, more user friendly and consume less bandwidth & storage.

In single page apps, each navigation doesn't require to a full refresh/reload of the website; instead only a small portion of the page needs to be loaded and shown to the user. There are many existing packages that can do this for you (jquery routing, Vue, Reach, etc...). But I prefer keeping it simple and lightweight. Here's how I did it using vanilla JavaScript & jQuery.

spa.js

$(window).on('hashchange', function(e) {
    codrRouter();
});

function codrRouter() {
  try {
      codrRouter_impl()
  } catch (err) {
      console.error(err)
      $.get('./views/500.html', function(pageContent) {
          $('.content').html(pageContent);
      }).fail(failedGet)
  }
}
Enter fullscreen mode Exit fullscreen mode

We define a page router (codrRouter) which will be the backbone for the navigation within the SPA. Notice that we use the "hashchange" event for triggering navigation. This means all our pages are identifier by the #hashtag identifier in the URL.

function codrRouter_impl() {
  var page = window.location.hash;

  if (page === '#' || page === '') {

    $.get('./views/home.html', function(pageContent) {
      $('.content').html(pageContent);
    }).fail(failedGet)

  } else if (page === '#challenges') {

    $.get('./views/challenges_levels.html', function(pageContent) {
      $('.content').html(pageContent);
    }).fail(failedGet)

  } else {

    $.get('./views/404.html', function(pageContent) {
      $('.content').html(pageContent);
    }).fail(failedGet)

  }
}

function failedGet() {
  const refresh = '<a class="refreshpage" href=".">refresh page</a>'
  $('.content').html('Oops, make sure you are online.<br>' + refresh);
}
Enter fullscreen mode Exit fullscreen mode

Now we implement the router and the possible routes. As you can see each matching route makes a GET request to get some html content. This content is only partial, and it will replace the existing code for our ".content" element which is just a placeholder. The final step is to make sure all a-href links are hashtags/anchors.

You can also programmatically navigate the users to different pages, by simply triggering the hashchange event:

window.dispatchEvent(new HashChangeEvent("hashchange"));
Enter fullscreen mode Exit fullscreen mode

It's as simple as that, and you don't need to use any 3rd party library. :)

Oldest comments (0)