技能使用指南

Apollo缓存策略Skill 用法详解

Apollo缓存策略Skillapollo-caching-strategies
14 个章节 约 22 分钟阅读 AI 智能生成

Apollo缓存策略Skill:让 AI 助手帮你写对 Apollo Client 的缓存逻辑

核心结论速览:

  • 它是什么:apollo-caching-strategies(技能ID:13987)是一个面向 AI 编程助手的能力包,把 Apollo Client 的缓存机制、获取策略、乐观更新、分页合并、持久化等一整套工程经验打包成可被调用的知识上下文。
  • 它解决什么:Apollo Client 的缓存能力很强,但配置细节多、容易踩坑(分页合并写错、突变后忘记更新缓存、敏感数据被持久化),这个技能让 AI 助手直接按最佳实践产出可用代码,而不是给出似是而非的示例。
  • 覆盖范围:缓存获取策略(cache-first / cache-and-network / network-only / no-cache 等)、读写缓存与片段、乐观更新与回滚、缓存驱逐与垃圾回收、响应式变量、偏移与游标分页、缓存持久化、缓存预热与重定向、缓存监控调试。
  • 适合谁用:正在用 React + Apollo Client 构建数据密集型应用、离线优先应用、社交/电商/仪表盘类前端项目的开发者。
  • 关键提醒:安装方式与可用入口请以官方说明为准;技能本身不改变你的业务代码,它的产出仍需你 review 后再合入。

该技能叫什么?如何一键安装 AI 技能提升开发效率?

技能基本信息

项目 内容
技能中文名 Apollo缓存策略Skill
技能英文名 apollo-caching-strategies
技能ID 13987
技能定位 面向 Apollo Client 缓存机制的知识型技能包
允许的工具 读取、写入、编辑、Grep、Glob、Bash
用户可调用 否(以官方说明为准)

这个技能要解决的问题非常具体:Apollo Client 的缓存是「规范化内存数据存储」,配置对了性能极佳,配置错了就是一地鸡毛。 比如分页合并函数 merge 写错会导致列表数据错位;突变(mutation)成功后忘记 update 缓存,UI 会出现「点了赞但数字没变」;keyFields 缺失会导致同一实体在缓存里存成多份;把 authToken 这类敏感字段一起持久化到 localStorage 则可能引发安全问题。这些都不是「会不会写 GraphQL」的问题,而是「有没有踩过坑」的问题。

这个技能把这些工程经验沉淀成 AI 助手可以直接调用的上下文,让它在生成或修改代码时自动对齐最佳实践。

「一键安装」的思路与步骤

技能详情中未提供具体的安装命令、仓库地址或安装入口,因此以下为通用思路,具体命令与入口请以官方说明为准:

  1. 确认前置条件:你的开发环境需要支持加载外部技能(Skill)的 AI 编程助手,并且项目本身已经使用或计划使用 React + Apollo Client(@apollo/client)。如果项目用的是其它 GraphQL 客户端,这个技能的收益会明显下降。
  2. 安装技能:在技能市场、技能目录或命令面板中搜索技能英文名 apollo-caching-strategies,或直接通过技能ID 13987 定位,按官方提供的方式添加。部分环境支持用命令行安装,具体以官方说明为准。
  3. 确认生效:安装后向 AI 助手提一个明确的技术问题来验证,例如「帮我写一个 Apollo InMemoryCache 配置,posts 字段按 filter 做 keyArgs 并支持基于 offset 的分页合并」。如果回答中出现 InMemoryCache、typePolicies、keyArgs、merge(existing, incoming, { args }) 这类符合官方模式的代码结构,说明技能已生效。
  4. 结合项目上下文使用:因为技能允许读取、写入、编辑、Grep、Glob、Bash 等工具,它可以在你已有的仓库里定位 apollo/cache.js、查询文件、mutation 文件,然后针对性修改,而不是给你一段脱离项目的示例代码。

一句话总结「提升开发效率」的逻辑:把「查文档 → 理解 → 试错 → 调试」的循环,压缩成「描述需求 → 生成符合最佳实践的代码 → review」的循环。

该技能的主要功能和特点

  • 缓存获取策略全覆盖:能区分并正确使用 cache-first(默认,先查缓存)、cache-only(只读缓存,不发请求)、cache-and-network(先用缓存立即渲染,再用网络数据更新,配合 notifyOnNetworkStatusChange 处理加载态)、network-only(总是请求并更新缓存)、no-cache(总是请求且不写缓存)、standby(类似 cache-first 但不自动更新,需手动 refetch)六种策略,并根据数据新鲜度需求给出选型建议。
  • 缓存的精细读写:支持 client.readQuery / client.writeQuery 按查询读写,client.readFragment / client.writeFragment 按片段读写,以及 cache.modify 做字段级增量修改(例如点赞数 +1、isLiked 置为 true),并用 cache.identify 稳定定位缓存对象。
  • 乐观 UI 与自动回滚:通过 optimisticResponse + update 组合,点击即更新界面,请求失败时乐观结果自动回退;对复杂场景(如新增评论)会先用 writeFragment 写入临时对象(形如 temp-${Date.now()} 的临时 ID),再挂到父实体的列表字段上。
  • 缓存驱逐与垃圾回收:提供 cache.evict 按对象或按字段驱逐、cache.modify + DELETE 批量清空列表、cache.gc() 回收无引用对象,并在删除类 mutation 的 update 中先用 readField 过滤列表再驱逐,避免内存泄漏与「幽灵数据」。
  • 响应式变量管理本地状态:用 makeVar / useReactiveVar 管理购物车、主题、弹窗开关、通知等本地状态,并通过 typePolicies 的 read() 把变量接入缓存查询,让本地状态和远端数据走同一套读取路径。
  • 分页合并策略:同时覆盖基于偏移(offset/limit)、基于游标(cursor + pageInfo)、以及 Relay 风格的 offsetLimitPagination 三种分页模型,并给出对应的 keyArgs + merge 配置。
  • 缓存持久化:配合 apollo3-cache-persist + LocalStorageWrapper 实现持久化,支持设置 maxSize、debug、trigger(write 或 background),并能对敏感字段做选择性排除。
  • 缓存预热与预取:应用启动时用 client.query 并行预热关键查询(当前用户、近期列表),或在链接 onMouseEnter / onTouchStart 时预取详情页数据,让跳转几乎瞬时完成。
  • 缓存重定向与计算字段:用 toReference 把查询字段重定向到已有缓存对象,用 readField 组合出 fullName 这类前端计算字段,避免重复请求与冗余存储。
  • 可观测与可调试:client.extract() 导出完整缓存、cache.watch() 监听变化、开发环境下挂载 window.apolloClient 与缓存体积监控、集成 Apollo DevTools。

和普通工具比强在哪? 普通代码补全只能给你「能跑」的片段,而这个技能给的是「按场景选型 + 配套的坑位规避」。它内置了 10 条最佳实践与 10 条常见陷阱(错误获取策略、缓存非规范化、内存泄漏、过度缓存、陈旧数据、突变后漏更新、错误合并逻辑、缓存颠簸、持久化泄露敏感数据、读取失败无错误处理),并在生成代码时主动规避。

如何使用该技能?

以下为分步骤使用指南,示例均可直接参考改造:

第 1 步:描述你的数据模型与分页方式。

给 AI 助手的输入示例:

我的项目用 Apollo Client,Post 类型的唯一标识是 id,User 用 email 作为唯一标识。posts 查询支持 filter、limit、offset 三个参数,需要支持「加载更多」时的列表合并。请帮我写 apollo/cache.js 的缓存配置。

预期输出:一段 new InMemoryCache({ typePolicies: { Query: { fields: { posts: { keyArgs: ['filter'], merge(...) } } }, Post: { keyFields: ['id'] }, User: { keyFields: ['email'] } } }) 结构完整的配置,merge 中会按 args.offset 把新数据写入数组对应位置,而不是简单拼接。

第 2 步:让技能帮你选获取策略。

输入示例:

详情页希望从列表页跳过来时立刻显示内容,但同时要保证数据是最新的,加载时要有个小 spinner。列表页数据可以接受几分钟的缓存。分别该用什么 fetchPolicy?

预期输出:详情页用 cache-and-network 并开启 notifyOnNetworkStatusChange,用 networkStatus === 1 控制 spinner;列表页用 cache-first。技能还会提醒你注意「对实时性要求高的数据误用 cache-first」这个常见陷阱。

第 3 步:为写操作补齐乐观更新与缓存同步。

输入示例:

我的点赞 mutation 叫 LIKE_POST,返回 Post { id, likesCount, isLiked }。希望点击后界面立刻变化,失败要回退,成功后缓存也要同步。

预期输出:useMutation 中同时给出 optimisticResponse(带 __typename)、update(cache, { data }) 里用 cache.modify + cache.identify 写回 likesCount 与 isLiked、以及 onError 中的失败处理说明(乐观结果自动回退)。

第 4 步:处理删除与缓存清理。

输入示例:

删除帖子后,列表里不能再出现它,缓存里也不该留着。

预期输出:update 中先 cache.modify 用 readField('id', ref) 过滤掉目标项,再 cache.evict({ id: cache.identify(...) }),最后调用 cache.gc()。

第 5 步:按需加上持久化、预热与调试。

输入示例:

我想把缓存持久化到 localStorage(上限 1MB),并且不要把 authToken 存进去;应用启动时预热当前用户和最近 20 条帖子;开发环境能打印缓存大小。

预期输出:persistCache + LocalStorageWrapper 的组合、maxSize: 1048576、对 authToken 用 read() 返回 null 做选择性排除、warmCache 中 Promise.all 并行预热、以及开发环境下定时打印 JSON.stringify(client.extract()).length 的监控代码。

第 6 步:验证与回归。

拿到代码后,务必在 Apollo DevTools 中确认缓存结构是否符合预期(实体是否被规范化、同一个 Post 是否只有一份),再跑一遍分页加载、点赞、删除的主流程。

同类型竞品对比分析

方案名称 定位 核心功能 安装/使用门槛 适用场景 优势与不足
Apollo缓存策略Skill(apollo-caching-strategies) AI 助手侧的 Apollo 缓存知识包 获取策略选型、缓存读写、乐观更新、驱逐、响应式变量、分页、持久化、预热、调试 需支持技能加载的 AI 编程环境 + 项目使用 Apollo Client;具体以官方说明为准 已有或计划使用 Apollo Client 的 React 项目,尤其是分页复杂、写操作多、需要离线的应用 优势:把最佳实践与常见陷阱前置到编码阶段,产出贴近官方推荐写法;不足:依赖 AI 助手的理解与你的描述质量,生成结果仍需人工 review
Apollo Client 手动配置(官方文档 + 自查) 官方原生能力 全套缓存 API 无额外安装,但需要通读文档并自行设计 typePolicies 任何 Apollo Client 项目 优势:最权威、可控性最强;不足:分页合并、乐观更新等细节的试错成本高,团队水平参差时质量不稳定
TanStack Query(React Query) 通用服务端状态管理库 查询缓存、失效、重试、乐观更新、分页 学习成本中等,不依赖 GraphQL,REST/GraphQL 均可 以 REST 为主或混合协议的项目 优势:API 简洁、缓存以查询键为中心,心智负担低;不足:没有规范化实体缓存,无法像 Apollo 那样按实体 ID 跨查询自动同步同一对象
Redux Toolkit + RTK Query 全局状态 + 数据请求一体化 请求缓存、标签失效、乐观更新 需要引入 Redux 体系,模板代码相对多 状态复杂、需要严格单向数据流的大型应用 优势:状态可预测、DevTools 强大;不足:配置成本高,缺少 GraphQL 原生实体规范化,需要手写大量适配
SWR 轻量数据请求 Hook 请求去重、聚焦重验、缓存 极低,几行代码即可上手 页面级轻量数据、营销站、后台简单列表 优势:轻、快、易上手;不足:不支持实体规范化与复杂分页合并,深层缓存一致性问题需自行处理

怎么选? 如果你的数据天然是「有 ID 的实体、跨页面共享、写操作后要多处同步」,Apollo Client 的规范化缓存是正解,此时这个技能的价值最大;如果只是页面级拉数据,SWR / TanStack Query 更省心;如果是大型团队协作且已有 Redux,RTK Query 更贴合。

该技能的典型应用场景与实际体验情况

场景一:社交媒体信息流(分页 + 点赞 + 评论)

角色与痛点:前端工程师维护一个无限滚动的社区信息流。痛点集中在三处——「加载更多」后列表顺序错乱;点赞后刷新页面数字又变回去;新增评论后要手动刷新才能看到。

使用方式:让技能生成 posts 字段的 keyArgs: ['filter'] + 基于 args.offset 的 merge;用 cache-first 渲染信息流;点赞走 optimisticResponse + cache.modify;新增评论用 writeFragment 生成临时对象后追加到 Post.comments 并把 commentsCount +1。

实际体验:上手难度中等,只要你能把「数据模型 + 分页参数 + mutation 返回结构」讲清楚,产出的代码基本可以直接用。效果最明显的是评论场景——乐观插入让交互等待感几乎消失。注意事项:临时 ID(temp-...)在服务端返回真实 ID 后需要被替换,否则可能出现重复项,务必在真实环境里跑一遍完整链路。

场景二:电商购物车与本地状态

角色与痛点:电商前端需要同时管理远端商品数据和本地购物车,过去用 Context + useReducer,组件层级一深就出现不必要的重渲染。

使用方式:用 makeVar 创建 cartItemsVar,通过 useReactiveVar 在组件内订阅,并在 typePolicies 的 Query.fields.cartItems.read() 中返回变量值,让购物车数据也能用 useQuery 读取。

实际体验:这是全套能力里最容易落地的一块,改动小、见效快,组件只在相关变量变化时更新。注意事项:响应式变量适合放「客户端本地状态」,不要拿它替代服务端数据缓存,否则会失去规范化缓存带来的实体同步能力。

场景三:内容管理后台(删除、编辑与缓存一致性)

角色与痛点:后台列表页、详情页、编辑页共享同一份文章数据,编辑保存后列表页仍显示旧标题;删除文章后缓存里还残留数据,DevTools 里能看到脏数据。

使用方式:编辑保存后由技能生成 cache.modify + readField 的字段级更新;删除时先过滤列表再 evict + gc;详情页用 toReference 做缓存重定向,避免重复请求。

实际体验:这是最能体现「规范化缓存」价值的场景,跨页面的数据一致性几乎不用手写同步逻辑。注意事项:如果某个列表查询的返回结构和实体结构不一致,readField 可能读不到字段,建议先在 DevTools 里确认缓存里的实际结构。

场景四:仪表盘与离线优先体验

角色与痛点:数据看板首屏加载慢,用户刷新后白屏几秒;移动端网络不稳时体验断崖式下降。

使用方式:用 persistCache + LocalStorageWrapper 持久化关键查询(maxSize 约 1MB),启动时 warmCache 并行预热「当前用户 + 最近列表」,列表链接加 onMouseEnter 预取详情。

实际体验:二次访问的首屏体验提升最直观,从「白屏 + spinner」变成「内容直出 + 后台静默刷新」。注意事项:持久化一定要做敏感字段排除(例如对 authToken 的 read() 返回 null),并定期 clearStore() 清理,避免旧数据长期滞留引发「看到的永远是旧版本」这类问题;同时留意 maxSize 超限后的写入失败。

该技能能为用户带来的价值

  • 效率提升:把「查文档 — 试错 — 调试」的循环压缩成一次对话。分页合并、乐观更新、驱逐清理这三类最容易反复调试的配置,从「半小时到几小时」缩短到「几分钟出初稿」。
  • 门槛降低:Apollo Client 的 typePolicies 对新手并不友好,keyFields、keyArgs、merge、read 的组合容易记混。技能让你不必先成为缓存专家,也能写出接近官方推荐结构的配置。
  • 质量收益:技能内嵌的 10 条最佳实践与 10 条常见陷阱,相当于把团队里的「踩坑清单」前置到了代码生成阶段,减少线上出现数据错乱、内存泄漏、敏感信息落盘这类高成本问题。
  • 可量化的收益方向:缓存命中率提升带来的重复请求下降、乐观更新带来的交互等待时间缩短、持久化与预热带来的二次访问首屏提速、内存占用与缓存体积的可观测性提升(extract() + 体积监控)。
  • 长期价值:缓存策略属于「写一次、长期生效」的基础设施。配置规范之后,后续新增的查询和 mutation 都能复用同一套模式,团队协作与代码评审的成本会持续下降。

常见问题 FAQ

Q1:这个技能怎么安装?装完怎么确认生效?

在支持加载技能的 AI 编程助手中,按官方说明搜索技能英文名 apollo-caching-strategies 或技能ID 13987 进行添加,具体命令与入口请以官方说明为准。验证方式是提一个明确的 Apollo 缓存问题(例如让助手配置带 offset 分页合并的 InMemoryCache),观察输出中是否出现 typePolicies、keyArgs、merge 等符合官方模式的写法。

Q2:这个技能收费吗?

技能本身是否收费、是否属于某个订阅套餐,取决于你所使用的技能平台或 AI 编程助手的计费规则,本文不做假设,请以官方说明为准。

Q3:我的项目用的是 REST / TanStack Query,还需要这个技能吗?

不需要。这个技能围绕 Apollo Client 的规范化缓存设计,核心概念(typePolicies、keyFields、cache.modify、readFragment)在其它库中并不通用。如果你的数据以页面级请求为主,TanStack Query 或 SWR 可能更省心;只有当「有 ID 的实体需要跨查询跨页面共享」时,Apollo 的规范化缓存才真正发挥优势。

Q4:技能生成的代码能直接上生产吗?

不建议直接合入。技能产出的是按最佳实践组织的代码骨架,但缓存行为与你的具体 schema、字段结构、分页参数强相关。建议先在 Apollo DevTools 中确认实体是否被正确规范化(同一个 Post 是否只有一份),再跑通分页加载、写操作、删除清理三条主链路,确认无误后合入。

Q5:为什么我配了 keyFields 和 merge,列表还是出现重复项?

常见原因有三个:一是 keyArgs 设置不当,导致不同参数组合被当成同一个字段或被拆成多个字段;二是 merge 中没有按 offset 定位写入位置,而是直接拼接数组;三是乐观更新产生的临时 ID 没有被服务端真实 ID 替换。这三类都属于技能里明确列出的「错误合并逻辑」与「缓存非规范化」陷阱,可以让助手对照你的实际配置逐项排查。