ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Polar 前端服务端跨请求 LRU 缓存实战:从 React.cache() 到 Fluid Compute 共享缓存

Polar 前端服务端跨请求 LRU 缓存实战:从 React.cache() 到 Fluid Compute 共享缓存 Polar 前端服务端跨请求 LRU 缓存实战从 React.cache() 到 Fluid Compute 共享缓存【免费下载链接】polarPolar — A billing platform for the intelligence era项目地址: https://gitcode.com/GitHub_Trending/po/polar导读本指南基于 Polar 仓库中.agents/skills/vercel-react-best-practices技能集的server-cache-lru.md规则系统讲解在 Next.js/React 服务端如何用 LRU 缓存实现「跨请求」数据共享。你会掌握React.cache()与lru-cache的职责边界、最小可运行实现、Vercel Fluid Compute 与传统 Serverless 下的缓存取舍以及 Polar 前端clients/apps/web中对应的真实缓存分层实践。React.cache() 的边界单请求内的去重在动手写 LRU 缓存之前先明确一个关键事实React.cache()只在一个请求的生命周期内生效。以 Polar 前端为例clients/apps/web的多个数据访问工具函数都使用了react包导出的cache()clients/apps/web/src/utils/user.tsgetAuthenticatedUser cache(_getAuthenticatedUser)从中间件写入的x-polar-userheader 解码出当前用户clients/apps/web/src/utils/order.tsgetOrderById cache(_getOrderById)封装GET /v1/orders/{id}并配合notFound()处理 404clients/apps/web/src/utils/organization.tsgetOrganizationBySlug cache(_getOrganizationBySlugCached)同类模式还出现在checkout.ts、customerPortal.ts、product.ts、subscription.ts、client/serverside.ts等工具文件中。其中user.ts的注释写得很直白// ...but tell React to memoize it for the duration of the request export const getAuthenticatedUser cache(_getAuthenticatedUser)也就是说同一个请求里多次调用getAuthenticatedUser()只有第一次真正读取 header/执行查询后续调用直接命中请求级缓存。这正是.agents/skills/vercel-react-best-practices/rules/server-cache-react.md所总结的 Per-Request Deduplication——对鉴权和数据库查询收益最大。但这解决不了跨请求问题用户点击按钮 A 再点击按钮 B这是两个独立的 HTTP 请求React.cache()的内存会在请求结束时释放第二次请求依然会重新查询数据库或上游 API。跨请求 LRU 缓存最小实现对于「多个顺序请求需要在几秒内反复读取同一份数据」的场景规则文档给出的方案是在模块级维护一个 LRU 缓存import { LRUCache } from lru-cache const cache new LRUCachestring, any({ max: 1000, ttl: 5 * 60 * 1000 // 5 minutes }) export async function getUser(id: string) { const cached cache.get(id) if (cached) return cached const user await db.user.findUnique({ where: { id } }) cache.set(id, user) return user } // Request 1: DB query, result cached // Request 2: cache hit, no DB query关键行为可以逐行拆解片段作用new LRUCachestring, any以请求参数如用户 id为 key、以查询结果为 value 的最近最少使用缓存max: 1000最多保留 1000 个条目超过后按 LRU 策略淘汰最久未访问的条目防止内存无限增长ttl: 5 * 60 * 1000每条目 5 分钟有效期过期后自动失效避免数据长期陈旧cache.get(id)命中即返回直接短路跳过数据库查询cache.set(id, user)未命中则写入写回缓存供后续请求复用lru-cache即 isaacs/node-lru-cache 所维护的 npm 包在 Polar 的依赖树中确实存在clients/pnpm-lock.yaml中锁定了lru-cache10.4.3与lru-cache11.5.2两个版本作为 Next.js 等依赖的传递依赖被解析。这意味着仓库内的工具链本身就运行在lru-cache之上。参数扩展不止 max 与 ttllru-cache的构造选项比规则示例更丰富在真实项目中可按下表按需启用选项说明max/maxSize条目数量上限或总字节数上限配合sizeCalculation可基于内容大小做容量控制ttl/ttlResolution/ttlAutopurge条目存活时间、过期检查精度ttlAutopurge开启后自动清理过期条目dispose(key, value, reason)条目被淘汰/删除时的回调可用于释放资源或记录淘汰原因evict、set、delete等noDisposeOnSet防止set覆盖时误触发disposeupdateAgeOnGet命中读取时刷新访问时间避免热点数据被误淘汰fetchMethod提供懒加载式取数函数cache.fetch(key)可自动回填缓存并支持请求合并request coalescingfetchMethod尤其值得关注它能按 key 合并并发请求多个请求同时 miss 同一个 key 时只执行一次底层查询——这在「多个顺序请求命中多个端点但需要同一份数据」的场景下能进一步削峰。适用场景何时该用跨请求 LRU规则文档给出了清晰的使用判据顺序的用户操作会命中多个端点、且这些端点在几秒内需要同一份数据时。典型场景包括用户连续点击导航多个页面/端点都要读取同一用户档案或同一组织信息商品详情、订阅详情等读多写少的数据在短时间内被不同接口反复引用需要在请求间共享鉴权/会话派生数据的计算开销。Polar 前端对此有配套实践。看 clients/apps/web/src/utils/organization.tsif (cached) { requestOptions.next { tags: [organizations:${slug}], revalidate: 600, } } else { requestOptions.cache no-cache }这里用 Next.js 的 fetch 缓存revalidate: 600即 10 分钟配合tags做按标签失效缓存组织查询并在未命中时降级为no-cache直取注释明确说明这是为了「避免新组织上线时的竞态同时保住 99% 场景下的缓存命中」。可以看到 Polar 的缓存策略是分层的请求级React.cache()去重 框架级 fetch 缓存 跨请求模块级 LRU三者各司其职LRU 补上的正是前两者覆盖不到的「跨请求、进程内、秒级」这一层。Fluid Compute 与传统 Serverless 的取舍规则文档对运行环境做了关键区分在 Vercel Fluid Compute 上LRU 缓存尤其有效。因为 Fluid Compute 允许多个并发请求共享同一个函数实例和内存模块级LRUCache会随实例存活而跨请求持久生效——无需引入 Redis 这类外部存储即可获得跨请求缓存。在传统 Serverless 中情况相反。每次调用都在隔离环境中运行函数实例随时可能被回收模块级内存缓存命中率不稳定跨进程共享则应考虑 Redis 等外部存储。因此落地 LRU 前需要先确认部署形态确定目标运行时是常驻实例Fluid Compute / 自托管长驻服务还是纯隔离函数若缓存数据必须在实例间强一致共享直接选择外部存储Redis而非进程内 LRU若数据只是「秒级窗口内的去重优化」进程内 LRU 是最轻量的方案——零外部依赖、零网络往返、命中即返回。实践要点与避坑清单结合规则文档与 Polar 仓库现状落地跨请求 LRU 时有几点值得注意模块级单例缓存实例必须定义在模块顶层如规则示例中的const cache new LRUCache(...)而不是函数内部否则每次调用都会新建空缓存给缓存设上限max与ttl缺一不可否则内存无界增长或数据永不过期缓存的是「可复用数据」而非「易变会话」写入前确认数据在 TTL 内允许陈旧对强一致要求的数据宁可每次直查与React.cache()配合而非对立同一次请求内用React.cache()去重请求间用 LRU 兜底Polar 的utils/目录就是两者共存的范例监控淘汰行为通过dispose回调统计淘汰原因判断max是否设置过小、缓存是否形同虚设。参考规则原文server-cache-lru.md配套规则请求内去重server-cache-react.mdPolar 实际应用clients/apps/web/src/utils/user.ts、order.ts、organization.ts依赖锁定证据clients/pnpm-lock.yamllru-cache10.4.3/lru-cache11.5.2【免费下载链接】polarPolar — A billing platform for the intelligence era项目地址: https://gitcode.com/GitHub_Trending/po/polar创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表