JS fetch: HTTP Caching instead of LocalStorage

Much simpler but slightly slower...

JS fetch: HTTP Caching instead of LocalStorage

Whenever you write plain JS without access to external libs, here is a quick hack on how to cache API responses, which I actually used for my homepage and in another small project.

The normal way

The JS function fetch makes remote calls really easy. But when you want to put some caching around it using localStorage (or CacheAPI), the code quickly becomes a little bulky:

// NORMAL: Fetch using localStorage as cache
const loadData = async (url) {
  var data = localStorage.getItem(url);

  if (data) { // check if expired
    data = JSON.parse(data);
    if (Date.now() - data.timestamp > 600000) { // 10mins
      localStorage.removeItem(url);
      data = null;
    }
  }

  if (!data) { // load fresh
    data = await fetch(url).then(response => response.json());
    data.timestamp = Date.now();
    localStorage.setItem(url, JSON.stringify(data));
  }

  return data;
}

My proposal

A very neat, but little-used solution for that, is to instead leverage the browser's internal HTTP cache, as shown below:

// PROPOSAL: Fetch using HTTP Caching
const loadData = async (url) => (
  url += "?cacheBust=" + ~~(Date.now()/60000/10/*mins*/),
  await fetch(url, {cache: "force-cache"})
    .then(response => response.json())
);

Here caching is accomplished by a combination of:
a) an additional parameter to the Url specifying the TTL and
b) an extra fetch-API parameter {cache: "force-cache"}

Unfortunately, there is no free lunch

First of all, keep in mind that some APIs might not like the additional parameter. Second, accessing the Browsers HTTP Cache (on disk) will take 2–10 ms, while response times from localStorage (in memory) are usually way below 1 ms.

Conclusion

Using this little hack, the code base becomes much leaner, with only a few minor disadvantages to keep in mind. For me, it's running fine for years. So if it suits your use case, don't hesitate to take this idea and share your feedback.