返回 AiToEarn
js-cache-storage.md
1 ---
2 title: Cache Storage API Calls
3 impact: LOW-MEDIUM
4 impactDescription: reduces expensive I/O
5 tags: javascript, localStorage, storage, caching, performance
6 ---
7
8 ## Cache Storage API Calls
9
10 `localStorage`, `sessionStorage`, and `document.cookie` are synchronous and expensive. Cache reads in memory.
11
12 **Incorrect (reads storage on every call):**
13
14 ```typescript
15 function getTheme() {
16 return localStorage.getItem('theme') ?? 'light'
17 }
18 // Called 10 times = 10 storage reads
19 ```
20
21 **Correct (Map cache):**
22
23 ```typescript
24 const storageCache = new Map<string, string | null>()
25
26 function getLocalStorage(key: string) {
27 if (!storageCache.has(key)) {
28 storageCache.set(key, localStorage.getItem(key))
29 }
30 return storageCache.get(key)
31 }
32
33 function setLocalStorage(key: string, value: string) {
34 localStorage.setItem(key, value)
35 storageCache.set(key, value) // keep cache in sync
36 }
37 ```
38
39 Use a Map (not a hook) so it works everywhere: utilities, event handlers, not just React components.
40
41 **Cookie caching:**
42
43 ```typescript
44 let cookieCache: Record<string, string> | null = null
45
46 function getCookie(name: string) {
47 if (!cookieCache) {
48 cookieCache = Object.fromEntries(
49 document.cookie.split('; ').map(c => c.split('='))
50 )
51 }
52 return cookieCache[name]
53 }
54 ```
55
56 **Important (invalidate on external changes):**
57
58 If storage can change externally (another tab, server-set cookies), invalidate cache:
59
60 ```typescript
61 window.addEventListener('storage', (e) => {
62 if (e.key) storageCache.delete(e.key)
63 })
64
65 document.addEventListener('visibilitychange', () => {
66 if (document.visibilityState === 'visible') {
67 storageCache.clear()
68 }
69 })
70 ```
71
71 lines MARKDOWN