GitHub Issues 导航提速:客户端缓存、预取与 Service Worker 如何把等待感降下来

GitHub Issues 通过客户端缓存、预取和 Service Worker,显著降低导航延迟。

冷月清谈:

GitHub 重新设计了 GitHub Issues 的导航架构,核心思路是把更多工作前移到客户端,减少重复网络请求和页面初始化带来的等待。新方案采用 local-first 思路:优先用浏览器本地已有数据渲染页面,再在后台同步最新状态。

技术上,GitHub 使用 IndexedDB 做持久化缓存,内存缓存承载会话内高频访问数据,并结合 stale-while-revalidate 策略,让用户回到已访问内容时能快速看到页面。团队还引入预热机制,根据用户导航习惯提前准备可能访问的数据;Service Worker 则负责拦截请求、检查本地资源,能命中缓存就先渲染,不能命中或数据过期再走后端。

效果上,即时导航体验比例从 4% 提升到 22%。P10 延迟从约 600ms 降到 70ms,P25 从 800ms 降到 120ms,中位延迟从 1200ms 降到 700ms,P75、P90 也有一定改善。文章也提醒,预取并非适用于所有场景,更可复用的模式是“先渲染页面外壳,再按缓存命中填充数据”。

怜星夜思:

1、这种“先显示缓存内容、后台再更新”的体验,你能接受到什么程度?
2、GitHub 这套缓存和预取方案,普通中小团队值得照着做吗?
3、预取到底是性能优化神器,还是容易制造脏数据和浪费流量的坑?
4、文章里提到不要只盯 p99,而要看整体延迟分布,你平时更关注哪个指标?

原文标题:GitHub Issues 大改造:用缓存和预取,让页面打开快了数倍

原文作者:AI前线

原文内容

作者 | Leela Kumili
译者 | 田橙

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/

图片会议推荐

做 AI 的谁还没点技术焦虑,来 AICon 深圳站,吃颗技术定心丸! 大会限时 9 折专属优惠,现在报名立减 580,更多详情可扫码或联系票务经理13269078023 进行咨询。

今日荐文

图片
你也「在看」吗?👇

关于“预取是不是神器”:它更像一把比较挑场景的工具。读多写少、数据图不复杂、用户路径可预测时很好用;如果数据变化频繁、权限复杂、写操作很多,预取出来的数据可能刚拿到就过期。

2 个赞

回答“先显示缓存内容、后台再更新”这个问题:我觉得要看业务场景。像 GitHub Issues 这种列表、详情页切换,先展示旧数据通常没问题,因为用户主要是找上下文。但如果是支付、库存、权限这种强一致场景,缓存哪怕旧几秒都可能出事故。

3 个赞

这个问题有点像外卖地图:骑手位置不一定每一秒都准,但你能先看到大概位置就会舒服很多。Web 应用也是,先给我一个可用的页面,比让我盯着 loading 强。

3 个赞

我觉得值得学思路,不一定学实现。GitHub 的关键不是“用了 Service Worker”,而是发现用户经常在固定路径里来回跳,于是复用已有数据。如果你的产品也有这种高频重复导航,就可以做;没有的话就是过度工程。

2 个赞

预取不是白嫖性能,它是拿带宽、缓存空间和复杂度换等待时间。用户下一步真去了,就赚了;没去,就是浪费。所以我觉得需要数据驱动,比如看命中率、取消率、额外请求量。

2 个赞

中小团队真别看 GitHub 做啥就跟啥,GitHub 的流量和使用频率不是一般产品能比的。你先把接口慢、SQL 慢、资源太大这些基础问题解决,可能比折腾预取更立竿见影。

2 个赞

我以前做过类似东西,最坑的是“预取了但不敢用”。因为页面进来还是要重新校验一堆状态,最后性能没快多少,代码还复杂了。所以文章里说“页面外壳优先 + 缓存填充”反而更现实。

2 个赞

回答延迟指标这个问题:我会先看中位数和 P75,因为它们更接近日常用户体验。p99 很重要,但经常被少量异常、网络抖动、极端用户环境拉偏,不能只靠它判断体验好坏。

2 个赞