GitHub Issues 通过客户端缓存、预取和 Service Worker,显著降低导航延迟。
冷月清谈:
技术上,GitHub 使用 IndexedDB 做持久化缓存,内存缓存承载会话内高频访问数据,并结合 stale-while-revalidate 策略,让用户回到已访问内容时能快速看到页面。团队还引入预热机制,根据用户导航习惯提前准备可能访问的数据;Service Worker 则负责拦截请求、检查本地资源,能命中缓存就先渲染,不能命中或数据过期再走后端。
效果上,即时导航体验比例从 4% 提升到 22%。P10 延迟从约 600ms 降到 70ms,P25 从 800ms 降到 120ms,中位延迟从 1200ms 降到 700ms,P75、P90 也有一定改善。文章也提醒,预取并非适用于所有场景,更可复用的模式是“先渲染页面外壳,再按缓存命中填充数据”。
怜星夜思:
2、GitHub 这套缓存和预取方案,普通中小团队值得照着做吗?
3、预取到底是性能优化神器,还是容易制造脏数据和浪费流量的坑?
4、文章里提到不要只盯 p99,而要看整体延迟分布,你平时更关注哪个指标?
原文标题:GitHub Issues 大改造:用缓存和预取,让页面打开快了数倍
原文作者:AI前线
原文内容
GitHub 重新设计了 GitHub Issues 背后的导航架构,通过将更多工作迁移到客户端,降低开发者感知到的延迟。工程团队引入了客户端缓存、预测性预取以及基于 Service Worker 的请求处理机制,提升了导航性能,使即时导航体验的比例从 4% 增加到了 22%。这些改动解决了大型 Web 应用中的一个常见挑战:减少由重复网络请求和客户端初始化导致的延迟,尤其是在频繁重复的工作流程中。
这项工作主要针对 GitHub Issues 用户展开,他们经常需要在 Issue、列表以及相关视图之间切换。过去已经获取的信息,现在可以被重新利用,而无需再次从后端服务获取。为了减少这些重复的网络依赖,GitHub 采用了一种本地优先(local-first)的方法:浏览器会立即使用已有数据进行渲染,同时后台进程会在需要时获取更新的信息。该架构使用了多个客户端存储层,包括用于持久化存储的 IndexedDB,以及用于活跃会话期间高频访问数据的内存缓存。
GitHub Issues 客户端架构
BareStack 强调了 预取(prefetching)方面一个重要的区别:
当数据图规模较小且以读取为主(例如 Issues)时,预取能够发挥作用。大多数应用拥有更大的数据图,并且存在读写冲突,因此预取的视图在进入页面后可能仍然需要重新获取数据。可复用的模式是“优先渲染页面外壳 + 基于缓存命中进行数据填充”,而不是预取本身。
Oguz Guven 也 指出 了另一个重要的性能优化经验:
从关注 p99 尾部延迟转向关注整体分布质量,是工程成熟度真正体现的地方。
缓存模型采用了 stale-while-revalidate(过期后重新验证)策略。当用户重新访问之前打开过的内容时,应用可以直接展示本地存储的数据,而无需等待服务器响应。随后,系统会在后台执行同步,更新缓存信息,并保持与后端数据的一致性。
GitHub 引入了预热(preheating)机制,以提升缓存效果。该机制会根据用户的导航模式,在用户发起请求之前提前准备可能需要的数据,并填充相关缓存条目。团队还进一步扩展了这一方案,引入了能够拦截浏览器请求并检查本地可用资源的 Service Worker。缓存数据可以立即渲染,同时后台更新会同步更新后的信息。对于不可用或已经过期的数据,请求仍会继续走正常的后端路径。
Service Worker 请求流程
该架构需要在响应速度和数据新鲜度之间取得平衡。GitHub 不再等待每次交互都必须先获取最新服务器状态再进行渲染,而是允许部分内容立即展示,并通过异步方式完成更新。这种方式降低了用户等待时间,同时保留了与后端系统的数据同步能力。
GitHub 高级软件工程师 Alexander Lelidis 解释说,团队认为延迟不仅仅是一项指标,他表示:
延迟不仅仅是一个指标。它是一种上下文切换。
GitHub 对导航延迟分布进行了测量。P10 延迟从大约 600 毫秒降低到了 70 毫秒,P25 从 800 毫秒降低到了 120 毫秒,中位延迟则从 1,200 毫秒降低到了 700 毫秒。P75 和 P90 延迟也有所改善,分别从 1,800 毫秒降低到了 1,400 毫秒,以及从 2,400 毫秒降低到了 2,100 毫秒。
原文连接:
https://www.infoq.com/news/2026/07/github-issues-navigation/
会议推荐



