mirror of
https://github.com/bitsocialnet/5chan.git
synced 2026-08-03 07:41:04 +02:00
* chore(ai-workflow): track repo-managed review tooling * fix(ai-workflow): remove repo-specific path assumptions Make shared workflow hooks and APK testing guidance resolve paths from the repo and contributor environment so the tooling works for all contributors, not just one machine.
71 lines
1.6 KiB
Markdown
71 lines
1.6 KiB
Markdown
---
|
|
title: Cache Storage API Calls
|
|
impact: LOW-MEDIUM
|
|
impactDescription: reduces expensive I/O
|
|
tags: javascript, localStorage, storage, caching, performance
|
|
---
|
|
|
|
## Cache Storage API Calls
|
|
|
|
`localStorage`, `sessionStorage`, and `document.cookie` are synchronous and expensive. Cache reads in memory.
|
|
|
|
**Incorrect (reads storage on every call):**
|
|
|
|
```typescript
|
|
function getTheme() {
|
|
return localStorage.getItem('theme') ?? 'light'
|
|
}
|
|
// Called 10 times = 10 storage reads
|
|
```
|
|
|
|
**Correct (Map cache):**
|
|
|
|
```typescript
|
|
const storageCache = new Map<string, string | null>()
|
|
|
|
function getLocalStorage(key: string) {
|
|
if (!storageCache.has(key)) {
|
|
storageCache.set(key, localStorage.getItem(key))
|
|
}
|
|
return storageCache.get(key)
|
|
}
|
|
|
|
function setLocalStorage(key: string, value: string) {
|
|
localStorage.setItem(key, value)
|
|
storageCache.set(key, value) // keep cache in sync
|
|
}
|
|
```
|
|
|
|
Use a Map (not a hook) so it works everywhere: utilities, event handlers, not just React components.
|
|
|
|
**Cookie caching:**
|
|
|
|
```typescript
|
|
let cookieCache: Record<string, string> | null = null
|
|
|
|
function getCookie(name: string) {
|
|
if (!cookieCache) {
|
|
cookieCache = Object.fromEntries(
|
|
document.cookie.split('; ').map(c => c.split('='))
|
|
)
|
|
}
|
|
return cookieCache[name]
|
|
}
|
|
```
|
|
|
|
**Important (invalidate on external changes):**
|
|
|
|
If storage can change externally (another tab, server-set cookies), invalidate cache:
|
|
|
|
```typescript
|
|
window.addEventListener('storage', (e) => {
|
|
if (e.key) storageCache.delete(e.key)
|
|
})
|
|
|
|
document.addEventListener('visibilitychange', () => {
|
|
if (document.visibilityState === 'visible') {
|
|
storageCache.clear()
|
|
}
|
|
})
|
|
```
|