服务端缓存与浏览器缓存的边界

**Redis 和 IndexedDB 不是可互换的两种缓存 —— 差别不在性能,在「缓存放在哪一层、给谁用」。**

判断规则:用户私有内容(笔记、剪藏正文)缓存在浏览器侧,不复制进服务端缓存;服务端 Redis 保留给队列、限流这类与用户内容无关的职责。不要因为「项目里已经有 Redis」就把 API 响应也塞进去。

RedisIndexedDB
位置服务端,应用与数据库之间浏览器,页面与网络之间
共享范围跨请求、跨用户(进程外)单浏览器、单用户
生命周期服务端 TTL / 淘汰策略控制跨会话存活,换设备即失效
典型用途队列、限流、会话、共享缓存离线数据、本地草稿、会话级内容缓存

三条推论:

  1. 缓存的目的是「少一次远端往返」时,两层都能做,但先问数据是不是用户私有。 私有正文进服务端缓存 = 把同一份私有数据再多复制一处,暴露面变大,而收益只在「多用户命中同一 key」时才成立 —— 个人知识库场景不成立。
  2. 「已经有 Redis」不等于「该用它做内容缓存」。 队列是进程内必需的基础设施,内容缓存是可选的优化,两者共用一套 Redis 不冲突,但职责要分开声明。
  3. 切栏目卡顿的修法不是「让列表接口带回全文」。 正确姿势是浏览器侧会话级缓存 + 请求去重 + 后台静默刷新:先拿缓存立即渲染,再在后台刷新,而不是把大字段塞回列表响应。

本日实例(mewmo):Web 端已同时使用远端 Upstash Redis 与远端 Neon,但 Redis 只服务 BullMQ,没有缓存笔记 / 剪藏的 API 响应,所以每次切栏目仍然访问远端数据库。方案定为浏览器会话级缓存 + 后台刷新,而不是把全文放进服务端缓存。

相关

  • 实时与异步 —— 队列与缓存常在同一套 Redis 上,但属于不同的时序模型
  • 缓存命中率 —— 服务端缓存的收益要用命中率衡量,浏览器缓存则看「是否省下这次请求」
  • 数据权威模型要先于同步与迁移确定 —— 「哪一层持有数据」和「哪一层持有缓存」是同一个模型问题的两面
  • 知识库先编译再查而不是查询时拼原文 —— 同属「在什么时刻、哪一层把数据整理好」的取舍
  • 列表切换要用master-detail而非重建列表 —— 浏览器侧缓存是为了让列表不被重建时仍能立即显示
  • 离线存储的三个等级 —— 从会话缓存到完整离线编辑的三个档位
  • 页面切换的四种刷新要分清 —— 先定位慢在哪一条链路,再决定用哪层缓存
  • 后台任务队列选型 —— Redis 去掉队列职责后,剩下的边界在哪