AI 书签仪表盘:一个 Chrome 扩展的开发故事
用真正有用的东西替换新标签页——我如何开发了一个 AI 驱动的书签仪表盘,以及我下次会怎么做。
我有 800 个书签,大部分都是废的。但里面藏着一些当时带着真实意图保存的链接——想读的文档、想试的工具、打算回来看的文章。每次打开新标签页看到 Chrome 默认页,我都会隐约想起那 800 个链接的存在,然后继续什么都不做。
书签仪表盘就是在这种挫败感里开始的。六个月后,它成了一个真正上架 Chrome 商店的扩展,开发过程让我对浏览器扩展开发的现状有了远超预期的认识。
想法
核心思路很简单:用一个功能完整的书签管理器替换新标签页。所有书签,打开即用。搜索、标签、文件夹、置顶——全都在一个界面里,不需要打开独立的应用或者翻书签菜单。
AI 层是后来加进去的。一旦在单个 JavaScript 上下文里拿到了用户的整个书签库,AI 就开始真正有用起来:
- 重复检测:找出 URL 相同或标题高度相似的书签
- 死链清理:检查哪些 URL 返回 404 或已经失效
- 标签建议:分析页面内容并推荐相关标签
- 一键整理:根据内容分析提出更合理的文件夹结构
这里的”AI 驱动”是实实在在的——AI 做的是手动处理会很枯燥的真实工作,而不仅仅是挂一个聊天框的名字。
技术决策
Chrome 扩展有一套特别的编程模型,三个互相隔离的执行上下文:
- 后台 Service Worker:持久运行(或按需启动),拥有完整的 Chrome API 访问权限,没有 DOM
- 内容脚本:注入到网页中,有 DOM 访问权,Chrome API 访问权有限
- 扩展页面(弹出框、新标签覆盖、选项页):普通网页,有 Chrome API 访问权
新标签覆盖在扩展页面上下文里运行,这意味着每次打开新标签页都会启动一个完整的 React 应用。我选了 React 18 做 UI,TypeScript 贯穿全局——不是因为必须这样,而是书签库的操作逻辑很快就会变复杂,类型系统能在那些”下拉框显示了错误文件夹”的 bug 出现之前就把它们拦住。
AI 功能通过后台 Service Worker 调用 Claude 的 API。如果从扩展页面直接发 API 请求,API Key 会暴露在网络请求里——让后台来代理调用,Key 就只存在于扩展的本地存储中。
Chrome 的限制
Manifest V3(当前扩展平台)比 V2 限制严格得多。Service Worker 不持久化——按需启动,一段时间不活跃后自动关闭。任何需要在 Service Worker 重启后还能用的状态,都得存进 chrome.storage。
最让人抓狂的限制是:Service Worker 里不能随意发起网络请求来检查 URL 是否存活。Chrome 的声明式内容安全策略默认拦截大部分出站 fetch 调用。我不得不用 offscreen API——一个 V3 的新特性,可以创建一个离屏文档——通过 DOM 的 fetch 来做 URL 有效性检查。这是个绕弯子的办法,为了一个简单的使用场景凭空增加了大量复杂度。
chrome.bookmarks API 的文件夹操作也出乎意料地受限。可以移动书签,但批量操作只能循环挨个调用 API,没有批量移动接口。对一个有 800 个书签的用户来说,整理一个文件夹的速度明显偏慢。
没人问起的功能 vs 人人都在用的功能
我花时间最多的是 AI 整理功能——分析你的书签结构,提出更好的文件夹层级。从代码角度来说,这是整个项目里技术上最有意思的部分。
几乎没人用它。
人人都在用的功能是基础搜索。对全部 800 个书签做全文搜索,一边输入一边出结果,支持键盘导航。这个功能我花了两天写完,却是用户在评论里最常提到的东西。
这是那个老生常谈的产品教训:解决每天都有的摩擦点,胜过解决偶尔才会遇到的大问题。整理书签一年也就做一次。搜索书签一天要做好几次。
如果重做
更好的离线处理。 AI 功能需要联网,但搜索和基础管理应该在断网状态下也能正常使用。我在一个用户坐飞机时报告了体验损坏之后才意识到这个问题。
多设备同步。 标签数据存储在扩展的本地存储里,Chrome Sync 默认不同步这个。在笔记本和台式机之间切换的用户,会发现另一台机器上标签都不见了。chrome.storage.sync 有 100KB 的限制——对大多数用户来说够用——但我一开始用了 chrome.storage.local,根本没考虑跨设备的使用场景。
更早测试性能边缘情况。 我开发时用的机器只有 200 个书签。第一个安装时有 3000 个书签的用户告诉我,新标签页要加载四秒。我不得不重新设计渲染方案,加上列表虚拟化。
扩展在 Chrome 商店可以找到,源码在 github.com/encoreshao/bookmark-dashboard。如果你曾经看着书签栏感到一阵莫名的愧疚,来试试看。