Loading source
Pulling the file list, source metadata, and syntax-aware rendering for this listing.
Source from repo
Apply 62 React and Next.js performance optimization rules from Vercel Engineering
Files
Skill
Size
Entrypoint
Format
Open file
Syntax-highlighted preview of this file as included in the skill package.
rules/js-cache-storage.md
1---2title: Cache Storage API Calls3impact: LOW-MEDIUM4impactDescription: reduces expensive I/O5tags: javascript, localStorage, storage, caching, performance6---78## Cache Storage API Calls910`localStorage`, `sessionStorage`, and `document.cookie` are synchronous and expensive. Cache reads in memory.1112**Incorrect (reads storage on every call):**1314```typescript15function getTheme() {16return localStorage.getItem('theme') ?? 'light'17}18// Called 10 times = 10 storage reads19```2021**Correct (Map cache):**2223```typescript24const storageCache = new Map<string, string | null>()2526function getLocalStorage(key: string) {27if (!storageCache.has(key)) {28storageCache.set(key, localStorage.getItem(key))29}30return storageCache.get(key)31}3233function setLocalStorage(key: string, value: string) {34localStorage.setItem(key, value)35storageCache.set(key, value) // keep cache in sync36}37```3839Use a Map (not a hook) so it works everywhere: utilities, event handlers, not just React components.4041**Cookie caching:**4243```typescript44let cookieCache: Record<string, string> | null = null4546function getCookie(name: string) {47if (!cookieCache) {48cookieCache = Object.fromEntries(49document.cookie.split('; ').map(c => c.split('='))50)51}52return cookieCache[name]53}54```5556**Important (invalidate on external changes):**5758If storage can change externally (another tab, server-set cookies), invalidate cache:5960```typescript61window.addEventListener('storage', (e) => {62if (e.key) storageCache.delete(e.key)63})6465document.addEventListener('visibilitychange', () => {66if (document.visibilityState === 'visible') {67storageCache.clear()68}69})70```71