当前位置:首页 > 问答 > 正文

缓存管理|前端开发:js代码如何设置缓存数据cache.js

用JavaScript玩转缓存管理

场景引入:那个加载慢到让人抓狂的页面

"这页面怎么又卡了?" 小张第3次刷新电商网站的商品列表页,手指不耐烦地敲击着桌面,每次点击都要重新加载全部数据,用户体验差到让人想摔键盘,作为前端开发,你很清楚——这时候就该缓存登场了。

缓存就像是你办公桌最顺手那个抽屉,把常用工具放在触手可及的地方,而不是每次用都要跑去仓库翻找,在前端开发中,合理使用缓存能让你的应用快如闪电,今天我们就来聊聊如何用JavaScript实现数据缓存。

基础篇:Web Storage API 缓存

localStorage - 持久化缓存

// 存储数据
function setLocalCache(key, value) {
  try {
    const data = JSON.stringify(value);
    localStorage.setItem(key, data);
    console.log(`成功缓存数据到localStorage: ${key}`);
  } catch (error) {
    console.error('localStorage存储失败:', error);
  }
}
// 读取数据
function getLocalCache(key) {
  try {
    const data = localStorage.getItem(key);
    return data ? JSON.parse(data) : null;
  } catch (error) {
    console.error('localStorage读取失败:', error);
    return null;
  }
}
// 示例使用
const productList = [{id: 1, name: "新款手机"}, {id: 2, name: "无线耳机"}];
setLocalCache('product_list', productList);
// 需要时取出
const cachedProducts = getLocalCache('product_list');
if (cachedProducts) {
  console.log('从缓存获取商品列表:', cachedProducts);
}

特点

  • 数据永久存储,除非手动清除
  • 同源策略限制(不同域名不能互相访问)
  • 存储大小通常为5MB左右

sessionStorage - 会话级缓存

// 存储会话数据
function setSessionCache(key, value) {
  try {
    const data = JSON.stringify(value);
    sessionStorage.setItem(key, data);
  } catch (error) {
    console.error('sessionStorage存储失败:', error);
  }
}
// 读取会话数据
function getSessionCache(key) {
  try {
    const data = sessionStorage.getItem(key);
    return data ? JSON.parse(data) : null;
  } catch (error) {
    console.error('sessionStorage读取失败:', error);
    return null;
  }
}
// 示例:存储用户当前会话的临时偏好
setSessionCache('user_theme_preference', 'dark');
// 页面刷新后仍可获取
const theme = getSessionCache('user_theme_preference');

特点

缓存管理|前端开发:js代码如何设置缓存数据cache.js

  • 标签页关闭后自动清除
  • 刷新页面不会丢失
  • 存储大小与localStorage相似

进阶篇:内存缓存实现

有时候我们需要更快的访问速度,可以使用纯内存缓存:

class MemoryCache {
  constructor() {
    this.cache = new Map();
    this.defaultTTL = 60 * 60 * 1000; // 默认1小时过期
  }
  set(key, value, ttl = this.defaultTTL) {
    const expireAt = Date.now() + ttl;
    this.cache.set(key, { value, expireAt });
    console.log(`内存缓存已更新: ${key}`);
  }
  get(key) {
    const item = this.cache.get(key);
    if (!item) return null;
    if (Date.now() > item.expireAt) {
      this.cache.delete(key);
      return null;
    }
    return item.value;
  }
  delete(key) {
    return this.cache.delete(key);
  }
  clear() {
    this.cache.clear();
  }
}
// 使用示例
const cache = new MemoryCache();
// 缓存API响应
cache.set('user_profile', {name: '张三', age: 28}, 30 * 60 * 1000); // 30分钟过期
// 获取缓存
const profile = cache.get('user_profile');
if (profile) {
  console.log('从内存获取用户资料:', profile);
} else {
  console.log('缓存已过期或不存在');
}

适用场景

  • 高频访问的临时数据
  • 不需要持久化的计算中间结果
  • 单页应用(SPA)中的状态缓存

实战篇:带自动刷新的缓存策略

结合内存缓存和localStorage,实现一个智能缓存系统:

class SmartCache {
  constructor() {
    this.memoryCache = new Map();
    this.syncQueue = new Set(); // 防止重复刷新
  }
  // 获取数据,如果过期会自动刷新
  async get(key, fetchFunc, ttl = 3600000) {
    // 1. 先检查内存缓存
    const memoryItem = this.memoryCache.get(key);
    if (memoryItem && Date.now() < memoryItem.expireAt) {
      return memoryItem.value;
    }
    // 2. 检查localStorage
    const localItem = getLocalCache(key);
    if (localItem && localItem.expireAt > Date.now()) {
      // 更新到内存缓存
      this.memoryCache.set(key, {
        value: localItem.value,
        expireAt: localItem.expireAt
      });
      return localItem.value;
    }
    // 3. 如果正在刷新,避免重复请求
    if (this.syncQueue.has(key)) {
      return localItem?.value || null; // 返回过期数据或null
    }
    // 4. 数据已过期,需要刷新
    this.syncQueue.add(key);
    try {
      console.log(`正在刷新缓存: ${key}`);
      const freshData = await fetchFunc();
      // 更新缓存
      const expireAt = Date.now() + ttl;
      this.memoryCache.set(key, { value: freshData, expireAt });
      setLocalCache(key, { value: freshData, expireAt });
      return freshData;
    } catch (error) {
      console.error(`刷新缓存失败: ${key}`, error);
      return localItem?.value || null; // 降级返回旧数据
    } finally {
      this.syncQueue.delete(key);
    }
  }
}
// 使用示例
const apiCache = new SmartCache();
// 模拟API请求函数
async function fetchUserData() {
  console.log('真实API请求...');
  // 这里应该是实际的fetch或axios调用
  return { name: '李四', lastLogin: new Date().toISOString() };
}
// 获取用户数据,会自动管理缓存
async function getUserData() {
  return apiCache.get('user_data', fetchUserData, 5 * 60 * 1000); // 5分钟缓存
}
// 在组件中使用
async function displayUser() {
  const userData = await getUserData();
  console.log('用户数据:', userData);
}
// 第一次调用会触发API请求
displayUser();
// 5分钟内再次调用会直接返回缓存
setTimeout(displayUser, 1000);

缓存策略选择指南

  1. 敏感数据:不要缓存,或使用极短的TTL(如验证码)
  2. 频繁访问的静态数据:localStorage + 内存缓存
  3. 大型数据集:考虑IndexedDB
  4. 会话状态:sessionStorage
  5. 实时性要求高的数据:内存缓存 + 短TTL

常见陷阱与解决方案

问题1:缓存雪崩

缓存管理|前端开发:js代码如何设置缓存数据cache.js

  • 现象:大量缓存同时过期,导致瞬间请求激增
  • 解决:为TTL添加随机偏移量,如 ttl * (0.9 + Math.random()*0.2)

问题2:内存泄漏

  • 现象:内存缓存不断增长
  • 解决:定期清理或使用LRU(最近最少使用)策略

问题3:缓存污染

  • 现象:错误数据被缓存
  • 解决:添加数据校验逻辑,缓存前检查数据结构

2025年的缓存新趋势

根据2025年8月的前沿实践,这些缓存技术值得关注:

  1. Service Worker缓存:更精细的离线缓存控制
  2. WebAssembly缓存:加速计算密集型任务的缓存复用
  3. AI驱动的缓存预测:基于用户行为预测哪些数据应该预缓存

缓存就像前端开发的"超能力",用得好能让你的应用快人一步,用不好反而会成为负担,记住几个黄金法则:

缓存管理|前端开发:js代码如何设置缓存数据cache.js

  1. 始终考虑缓存失效策略
  2. 多层缓存配合使用效果最佳
  3. 缓存不是万能的,某些场景下主动放弃缓存反而更好

去给你的项目加上合适的缓存吧,用户会感谢你的!

发表评论