Recently I was developing a web application for a client. All was going well in development till it moved to production, where I had to face a new problem that lead to many a sleepless night.
The end-users for our application were mostly from India. You might be aware of the fact that over 85% of the Indian population is plagued by slow internet issues. Because of this people were unable to load the app and this turned into a major issue.
When I searched the internet on the topic, I found that Google and Bing are using localStorage extensively for storing the SCRIPTS for subsequent pageviews. Being curious as a developer, I tried to find whether Google and Bing are using something unique to achieve the performance benchmark? This is where I was introduced to the basket.js project by Addy Osmani.
Basket.js is a small javascript library which provides caching of scripts in localStorage.
Every time your browser loads a specific page, it loads all the script files linked to it. Let’s say a visitor opens/ refreshes your website 20 times a day and has to wait for the scripts to load every time, before he can actually perform a desired action.
“So what can we do to improve the performance?”
Now think of the possibility to save the scripts locally when the user visits the page for the first time. This will enable the page to check for local availability of the scripts, when the user re-visits the website and if the scripts are not found they will simply be loaded from the server.
Basket.js checks if the script(s) have previously been saved locally in browser’s localStorage. If so then they will simply be loaded and injected into the current document. If not, they will be loaded via XHR, but cached so that no additional script loads are required in the future.
You must be wondering why Basket.js is using localStorage instead of the browser cache or IndexedDB as both the latter are well popular, right? Let me present some test statistics in front of you:
It’s very easy to integrate Basket.js with your existing project. Just follow these steps:
Step 1: Include the basket.js library script in your <head> tag :
<script type="text/javascript" src="lib/basket.full.min-0.0.3.js"></script>
Step 2: Require your app files using BasketJs’s require api:
//require jquery basket.require({ url: "https://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js", key: 'jquery' })
Step 3: Use the promise provided by Basket.js api to order dependencies:
basket .require({ url: "https://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js", key: 'jquery' }) .then(function() { //success! jquery is loaded you can load dependent scripts now basket.require({ url:"https://ajax.googleapis.com/ajax/libs/jqueryui/1.11.4/jquery-ui.min.js", key: 'jquery-ui' }) }, function() { //error! jquery is not loaded })
The require api returns a ‘promise’ which you can use to manage the dependency among scripts. Here jquery-ui is dependent on jquery so we put that inside success callback of the promise. You can pass two parameters as promise callback: first one is success and second one error callback.
Step 3: Set the expire or the unique property to determine whether to load cached or fresh version of the scripts:
You can set the expiry for your scripts by setting the expire property by number of hours, after which the cached file will be considered as invalid item.
//require jquery basket.require({ url: "https://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js", key: 'jquery', expire: 1 //number of hours after which it is expired })
You can also set the unique property which will be used to determine the invalid state of the cached scripts. If the unique value is different than previous then it will load a fresh version else loads the cached version.
//require jquery basket.require({ url: "https://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js", key: 'jquery', unique: 'v1.0' //your app version which is used to determine the validity. })
You can use your application’s version text as unique so that when a new version arrives it automatically loads the new scripts.
Thanks to Addy Osmani for this project which helped me to achieve the desired performance benchmark. check out his project page.
[button id=”exmple_git” class=”btn-primary” link=”https://github.com/rajubera/basketjs-example” linking=”default” size=”medium” type=”” title=”Download the demo project from here” bg_color=”#2077bb”]Download demo project[/button]
Thanks for reading. Hope this article helps you to improve the performance for your website or web application. Do comment below to let me know your feedback.