Implement caching in js fetch API
- How we can reduce repeated API calls with cache
- Discussion on flow chart
- Cache mechanism with cache hit, miss
With the rise in web application and demand for asynchronous data loading we got to see XMLHttpRequest, ajax, and now fetch. Its 2021 and applications are highly dependant on asynchronous data loading may be for loading search suggestion, load more comments on a tread, load content on scroll etc. So isn't this the time to leverage some techniquies through which we can make api consumption and network calls more effective? Hell, yeah ! there is always possibilies of improvement on exisitng technologies, so in this post we will see how few lines of code can reduce upto 76% network calls.
PS. I was inspired by Android's volley library and hence decided to write my own set of code to implement cache in network calls and make network calls efficient
Who should read this post 🤔?
If your web application have search bar, pagination, loads same content via api call multiple times, then you should definitely give it a try.
Let's start☕
We will use javascript fetch API to retrive data from API. We will type in a input box and fetch the related results and display them on DOM. Below is the basic block diagram of normal code flow.
Below is the basic block diagram representing the flow of our code execution. we will learn how to make a cusotm ajax function that implements cache
Bit more in depth 😬
The below block diagram outlines behind the scene of our custom ajax function which implements cache
Let's break🔨 the complexities
- User types
- calls a function on every keystroke
- call custom ajax function to fetch data
- Result returned are displayed on screen
- Generate md5 hash of the url and data
- Check if data for the hash exists in cache
- Return data if cache hit
- For cache miss fetch data
- Store in cache
- Return data to callback function
- Hurrah! we reduced >70% network calls and >70% less load on server
HTML code for the input box and a div for showing results
<div class="wrap">
<input oninput="on_type(0,this.value)">
<div id="results"></div>
</div>
This function will be triggered while typing on the input box
//to store the cached data
var cache=[];
function on_type(r=0,val=null){
//before api call
if(!r){
ajax((`fetch.php?search=${val}`),on_type);
}
//after api call
else{
//populate the DOM with the results
let codes = r.results.map(e=>`${e.name}`).join('');
document.getElementById('results').innerHTML = codes;
}
}
Code of our custom ajax() that implements caching
function ajax(url,callback){
//to get unique string for each unique api calls
let hash = md5(url);
//check if data exists in cache
let item = cache.find(e=>e.hash==hash);
//return cached data if found
if(item) return callback(item.r);
fetch(url)
.then(response => response.json())
.then(response => {
save_in_cache(hash,response);
return response;
})
.then(callback)
.catch(error => console.log(error));
}
function save_in_cache(){
//store in cache
cache.push({hash,r:response})
//store max 50 call's data else it might end up consuming lot of memory
if(cache.length>50) cache.splice(0,(cache.length-50));
}
See what we achieved
This gif shows out of 90 network calls 69 were cache hits thus only 24% were actual network calls and 76% were served from cached. Isn't it worth adding those few lines of code?
Ding ding ding... 💃ðŸ¼ðŸ’ƒðŸ¼
Thats how we can implement caching in network calls, hope you got some basic idea and you could levearage localStorage sessionStorage to take caching to another level.