Caching XHR Responses in Local Storage

davecozens

Dave Cozens

Posted on October 12, 2021

Caching XHR Responses in Local Storage

So, I've been working on my site recently - https://uktidetimes.com/ - and it occurred to me that since I'm serving content that only changes once a day, there's really no reason for the same user to repeatedly hit the service.

I was already using Axios for my XHR requests, so I've put together an NPM module that wraps Axios but adds additional caching capabilities using local storage in the browser.

There's two primary benefits to this:

  • It reduces the amount of traffic to my API (which is running on AWS Lambda) - therefore reducing costs.
  • It improves load time for the user if they've already views this data

https://www.npmjs.com/package/xhr-cache-with-ttl

As a coder, I obviously want to do as little typing as possible so I wanted to take the approach of wrapping a known-awesome HTTP request library (in this case Axios) because most of the work has been done already. Nobody wants to reinvent that wheel today, thank you.

function xhrCache(method, url, options = {}) {
    return new Promise(function (resolve, reject) {
        axios[method](url, options).then((res) => {
            resolve(res)
        })
    })
}
Enter fullscreen mode Exit fullscreen mode

Nice and easy. Axios wrapped in a promise, passing through the method, URL and options attributes that it already uses.

This just left me to throw together a basic caching mechanism.

I decided that I'd create two keys in local storage per cached request - one for the metadata (TTL and timestamp) and one for the response. This avoids a potentially heavy deserialisation cost of expired cache items.

I'm using the URL of the request as part of the key in local storage. This helps with diagnosing any issues but there's an argument for hashing it for brevity (and differentiating more complex requests). Maybe for another day.

The flow of the function is nice and simple.

if (cache exists && cache not expired){
    return cached content
} else {
    fetch content using Axios
    cache content
    return content
}

Enter fullscreen mode Exit fullscreen mode

The whole thing comes in at less than 100 lines of code, and it's open source so feel free to make off with it :)

https://github.com/davecozens/xhr-cache-with-ttl

How to use it

const result = await xhrCache("get", url, { ttl: 600 })
Enter fullscreen mode Exit fullscreen mode
πŸ’– πŸ’ͺ πŸ™… 🚩
davecozens
Dave Cozens

Posted on October 12, 2021

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related