JAVASCRIPT
Simple Client-Side API Caching with `localStorage`
Optimize web application performance by implementing a basic client-side API cache using `localStorage` to store and retrieve frequently accessed data.
const API_CACHE_PREFIX = 'api_cache_';
const CACHE_LIFETIME_MS = 5 * 60 * 1000; // 5 minutes
/**
* Fetches data from an API, first checking if a valid cached response exists in localStorage.
* Caches new responses with a timestamp.
* @param {string} url - The API endpoint URL.
* @param {object} options - Fetch API options.
* @returns {Promise<any>} - A promise that resolves with the API response data.
*/
async function fetchWithCache(url, options = {}) {
const cacheKey = `${API_CACHE_PREFIX}${url}`;
const now = new Date().getTime();
// Try to retrieve from cache
try {
const cachedItem = localStorage.getItem(cacheKey);
if (cachedItem) {
const { data, timestamp } = JSON.parse(cachedItem);
if (now - timestamp < CACHE_LIFETIME_MS) {
console.log(`[Cache Hit] for ${url}`);
return data;
} else {
console.log(`[Cache Expired] for ${url}`);
localStorage.removeItem(cacheKey); // Remove expired item
}
}
} catch (e) {
console.warn(`Error parsing cache for ${url}:`, e);
localStorage.removeItem(cacheKey); // Clear potentially corrupt cache
}
console.log(`[Fetching Live] for ${url}`);
try {
const response = await fetch(url, options);
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
const liveData = await response.json();
// Cache the new data
try {
const itemToCache = JSON.stringify({ data: liveData, timestamp: now });
localStorage.setItem(cacheKey, itemToCache);
} catch (e) {
console.warn(`Error caching data for ${url}:`, e);
// If storage limit is exceeded or other caching error, proceed without caching
}
return liveData;
} catch (error) {
console.error(`Error fetching data for ${url}:`, error);
throw error;
}
}
// Example Usage:
/*
(async () => {
const postUrl = 'https://jsonplaceholder.typicode.com/posts/1';
console.log('First call (should fetch and cache):');
await fetchWithCache(postUrl).then(data => console.log('Data:', data.title));
console.log('
Second call (should use cache):');
await fetchWithCache(postUrl).then(data => console.log('Data:', data.title));
// To test expiration, wait 5 minutes or manually set a past timestamp in localStorage
// or change CACHE_LIFETIME_MS to a very small number like 1000 (1 second) for testing
})();
*/
How it works: This JavaScript snippet provides a `fetchWithCache` function that first attempts to retrieve data from `localStorage`. If a valid, unexpired entry exists, it returns the cached data, preventing an unnecessary API call. Otherwise, it performs a live `fetch` request, stores the new data along with a timestamp in `localStorage`, and then returns it. This simple caching mechanism helps reduce network requests, improve load times, and lessen the burden on the API server for frequently accessed, non-real-time data.