src/services/cache.js that stores API responses in localStorage alongside a timestamp. On the next request the cache is checked first; only if the data is older than five minutes does the app hit the network again.
TTL check
Every cache function applies the same age check before deciding whether to serve cached data or fetch fresh data:Date.now() returns milliseconds since the Unix epoch. cacheDate is the timestamp stored as a string when the data was last fetched. Converting it with Number() and comparing the difference to 300 000 ms (5 minutes) keeps the logic self-contained and dependency-free.
Cache functions
Each function follows the same read-check-write pattern. The only differences are the localStorage key names and the underlying API call.keepInfo()
Caches the top 20 cryptocurrencies by market cap fetched from CoinGecko.| localStorage key | Contents |
|---|---|
getInfoCrypto | Serialised array of top-20 coin objects |
getInfoCryptoDate | Unix timestamp (ms) of last fetch |
keepNews()
Caches Spanish-language market news from CryptoCompare.| localStorage key | Contents |
|---|---|
getNewsCrypto | Serialised news response object |
getNewsCryptoDate | Unix timestamp (ms) of last fetch |
keepPrice()
Caches spot prices for a fixed set of coins (Bitcoin, Ethereum, Solana, Cardano, Tether, BNB) used by the converter page.| localStorage key | Contents |
|---|---|
getPriceCrypto | Serialised price map ({ bitcoin: { usd: ... }, ... }) |
getPriceCryptoDate | Unix timestamp (ms) of last fetch |
keepHistory(cryptoId, days)
Caches historical price chart data. Because every coin and time-range combination is a distinct dataset, the key is dynamic.history_bitcoin_7 and history_bitcoin_7Date. Switching to a 30-day view writes a separate pair, so both remain cached independently.
Cache lookup flow
Read localStorage
The cache function reads the data key and its companion timestamp key from
localStorage.Check age
If both values exist and
Date.now() - Number(cacheDate) < 300 000, the cached data is still fresh.Serve from cache
The cached string is parsed with
JSON.parse() and returned immediately — no network request is made.Fetch on cache miss
If the cache is empty, missing, or expired, the underlying API function is called (
getTopCryptos, newsApi, priceApi, or getHistoryCrypto).Trade-offs
Per-browser storage
Per-browser storage
localStorage is scoped to the origin and the browser profile. A user opening the app in a different browser, a private/incognito window, or on a different device starts with an empty cache and will trigger fresh API calls.
No cross-tab invalidation
No cross-tab invalidation
If a user has the app open in two tabs, each tab manages its own in-memory state. When one tab refreshes the cache, the other tab does not know until it runs its own cache check. In practice this is harmless because price data is not user-generated.
Cleared with localStorage
Cleared with localStorage
Calling
localStorage.clear() (e.g., from browser DevTools or another script on the same origin) removes all cached data. The next load fetches everything fresh.Storage size
Storage size
Browsers cap localStorage at ~5 MB per origin. Historical chart data for many coins and ranges can accumulate. If storage fills up,
localStorage.setItem throws a QuotaExceededError and the cache write silently fails in the current implementation.The 5-minute TTL is hardcoded. Crypto prices can move significantly within that window. For production use, consider making the TTL configurable per data type — shorter for prices, longer for news.