整理浏览器书签这件事,很多人隔一段时间就会做一次。把散落在各个平台里的链接归拢起来,按主题分好类,以后找起来能省不少时间。作者最初也是这个打算。他重新打开自己曾经用过的几个书签管理器,想把数据重新分配一遍,让以后的使用更顺手。

一个意外的发现

打开网易新闻 查看精彩图片

在这些管理器里,Raindrop 积累了不少内容。于是他安装了这款软件的开源桌面客户端,准备动手整理。但很快,一个奇怪的现象引起了他的注意:这个原生应用几乎每做一次操作,界面就会刷新一次。为了确认问题,他直接断开了网络。结果很明显,应用变得无法正常使用。

对于需要离线整理书签的人来说,这个限制让人失望。不过作者没有停留在抱怨上。他想到,也许可以自己动手修复这个问题,让所有使用者都受益。随后,他提交了拉取请求,并开始记录整个过程。

先缩小范围,再理解代码

作者坦言,自己最近几个月更多时间花在想法上,代码写得少了。面对一个别人写的代码库,他没有选择一上来就通读全部代码。他的做法是:在开源项目里,先限定工作范围。既然没有额外的维护责任,就不必把时间花在理解整个架构上。拿到代码后,他直接把它放进了 Linux 上的 Antigravity 应用里开始查看。

最初的判断是,桌面端可能根本没有在客户端保存书签数据。于是他打开了桌面端源码,里面包含一个 webapp 子模块。他询问了其他人的意见,想知道在刷新数据加载完成之前,书签应该以什么方式存储。对方给出的回复里提到,这并不是真正的缓存,但具体方案还需要进一步确认。

缓存其实存在,只是藏在了另一个仓库

接下来的回复让他有些意外。根据说明,缓存是存在的。那为什么看起来没有生效?继续读下去,对方提到了“Collections”这个子标题。他重新检查了自己看到的行为:原来他之前为了整理,已经把集合都删掉了,之后只是在侧边栏的过滤器里来回切换。而集合页面本身确实是被缓存的。

更关键的信息是,整块逻辑并不在桌面端包装器里,而是在 webapp 仓库中。这一次,他仔细阅读了架构报告,也浏览了一部分代码,然后把当前工作目录切换到了 webapp 仓库。经过反复测试,他给出了修正后的查询。

对方的回复确认了他的推断,并给出了精确的机制说明。webapp 的书签缓存是一个键值存储,键由路由的第一段决定,也就是 state.bookmarks.spaces[spaceId]。集合则使用自己的 collectionId 作为键。

问题到这里逐渐清晰:缓存逻辑本身存在,但键的设计和实际使用场景之间存在错位。用户在没有集合、只在侧边栏过滤器里操作时,无法命中原本为集合页面准备的缓存。这个发现也解释了为什么断网后应用会变得不可用。

整个修复过程没有引入新的功能,也没有改变产品方向,只是让原本就存在的缓存机制在更多场景下真正发挥作用。对于习惯离线整理书签的用户来说,这个改动带来的体验提升是直接的。