JAVASCRIPT

Client-Side Caching of API Responses with localStorage

Improve web application performance and reduce redundant API calls by implementing a simple client-side caching mechanism for API responses using `localStorage` with an expiration time.

const CACHE_PREFIX = 'api-cache-';
const CACHE_EXPIRATION_MS = 5 * 60 * 1000; // 5 minutes

async function fetchWithCache(url, options = {}) {
    const cacheKey = CACHE_PREFIX + url;
    const now = Date.now();

    // 1. Try to retrieve from cache
    const cachedData = localStorage.getItem(cacheKey);

    if (cachedData) {
        const { timestamp, data } = JSON.parse(cachedData);
        if (now - timestamp < CACHE_EXPIRATION_MS) {
            console.log('Returning cached data for:', url);
            return data; // Return cached data if not expired
        } else {
            console.log('Cached data expired for:', url);
            localStorage.removeItem(cacheKey); // Remove expired data
        }
    }

    // 2. Fetch from network if no cache or expired
    console.log('Fetching from network for:', url);
    try {
        const response = await fetch(url, options);
        if (!response.ok) {
            throw new Error(`HTTP error! Status: ${response.status}`);
        }
        const data = await response.json();

        // 3. Cache the new data
        localStorage.setItem(cacheKey, JSON.stringify({
            timestamp: now,
            data: data
        }));

        return data;
    } catch (error) {
        console.error('Error fetching data:', error);
        throw error;
    }
}

// Example Usage:
// (async () => {
//     // First call will fetch and cache
//     const users1 = await fetchWithCache('https://jsonplaceholder.typicode.com/users/1');
//     console.log('Users 1:', users1);

//     // Second call (within 5 minutes) will return cached data
//     const users2 = await fetchWithCache('https://jsonplaceholder.typicode.com/users/1');
//     console.log('Users 2 (cached):', users2);

//     // You can test expiration by adjusting CACHE_EXPIRATION_MS or waiting
//     // console.log('Waiting for cache to expire...');
//     // await new Promise(resolve => setTimeout(resolve, CACHE_EXPIRATION_MS + 1000));
//     // const users3 = await fetchWithCache('https://jsonplaceholder.typicode.com/users/1');
//     // console.log('Users 3 (re-fetched after expiration):', users3);
// })();
How it works: This JavaScript snippet demonstrates a client-side caching strategy for API responses using `localStorage`. It wraps the standard `fetch` API, first checking if the requested data exists in `localStorage` and is still within its defined expiration period. If valid cached data is found, it's returned immediately, reducing network requests and improving application responsiveness. Otherwise, a network request is made, and the fresh data is stored in `localStorage` along with a timestamp for future use. This is a simple yet effective way to optimize performance for frequently accessed but infrequently changing data.

Need help integrating this into your project?

Our team of expert developers can help you build your custom application from scratch.

Hire DigitalCodeLabs