我那个记笔记的小网页,上个月终于不再让朋友在高铁上骂街了。以前一进隧道页面就白屏,刷新十次,加载图标转得像陀螺——现在她发微信说:“刚在3号线上改了三条待办,出站时顺手点开网页,全同步好了。”
这事儿得倒着说。先说结果:它现在跑在 Chrome、Edge、Safari 甚至旧版 Firefox 上都稳,gzip 后才 46KB;底层靠 IndexedDB 或 WebSQL,但你压根不用碰事务、游标、对象存储这些词;API 简单到像写日记:new PouchDB('my_notes'),敲完回车,本地数据库就活了。
其实我最早试的是 localStorage。存个“今天吃了豆浆油条”没问题,但存到第17条笔记时,JSON.parse(localStorage.getItem('notes')) 开始报错——它不认换行符,也不管嵌套对象,更别说搜“标题含‘React’且创建时间大于上周”。那会儿我还真手写过一个过滤器,三重 for 循环套着正则,跑一次要 200ms,手机上直接卡成幻灯片。
直到 Alba Herrerías 在 2012 年放出 PouchDB 的第一个 tag。这位西班牙女程序员没搞什么高大上的发布会,就往 GitHub 丢了个 README,写着“CouchDB in the browser”。我去年翻她博客,发现她吐槽过:“别再让我解释为什么不用本地存储了——它连‘删除某条’都要先读全量再 filter 再存回,这叫数据库?”
真正让我坐直身子的是那天改同步逻辑。原计划是写个“离线队列 + 联网后手动 POST”,结果只加了这一行:

db.sync('https://api.myapp.com/db', { live: true, retry: true })
然后它就自己干了:网络断掉时缓存变更,恢复后自动比对 MVCC 版本号,冲突时把两个 _rev 都留着,像留两份手稿等你裁决。我故意在手机端和电脑端同时改同一条笔记的标题,再连网——弹出的不是报错,是一段 JSON,里面清清楚楚列着 conflicts: true 和两个 _rev 值。
它也能跑 Node.js。我同事拿它搭了个内部知识库原型,不装 MongoDB,就用 require('pouchdb-server') 启个轻量服务,数据全落本地文件,部署到 Vercel 都行。Apache-2.0 协议,公司法务扫了一眼就批了。
上周我删掉所有 console.log,把项目推上 GitHub Pages。有用户留言说:“地铁10号线从西二旗到知春路那四分钟,是我一天里唯一能安静补完周报的黄金时段。”
对吧?
一个十年前开源的项目,至今没上热搜,文档里还夹着 2015 年的截图,可它真把“离线”这两个字,从功能列表里摘下来,塞进了用户手指划过屏幕的节奏里。
我昨天又测了次——断网状态下新建三条笔记,关机,重启,连 Wi-Fi,32 秒后所有改动都出现在服务器后台的 MongoDB Compass 里。
连个加载动画都没显示。