现在的软件默认假设一件事:你的数据应该存在别人的服务器上。照片存云相册、笔记存云笔记、行程存云地图。方便确实方便,但我一直觉得这个默认设定哪里不对劲。
一个我觉得不对劲的默认设定
问题不在于「云不好」,而在于所有权被悄悄转移了:
- 服务一停,你的数据就打不开;
- 改一次隐私政策,你的数据就可能被拿去训练模型;
- 断网了,很多「本地」应用其实只是「本地界面 + 远程数据」,一样用不了;
- 你想导出,往往只能拿到一堆结构被打乱的 JSON。
这些都是我自己在整理照片、笔记、旅行足迹时真实遇到的问题。于是我开始按 local-first 的原则重做自己的工具。
local-first 到底意味着什么
local-first 不是「反对云」,而是把主副本放在你自己的设备上,云降级为备份与同步的一个节点。它通常有七条理想特性(Ink & Switch 那篇著名文章提出的):
| 特性 | 通俗解释 |
|---|---|
| 快速 | 读写都在本地,不等网络 |
| 多设备 | 手机、电脑的数据能同步 |
| 离线可用 | 没网照样能用 |
| 协作 | 需要时也能多人一起改 |
| 长期保存 | 服务商倒闭,数据还在你手里 |
| 隐私安全 | 数据不离开你的设备也能用 |
| 用户拥有 | 随时能完整导出 |
我的工具里,前三条是底线:打开就能用、多设备能同步、断网不掉链子。后面几条是努力方向。
它没有免费午餐:代价是什么
讲实话,local-first 要付代价,我不打算藏着:
- 同步冲突:两台设备离线各改各的,同步回来怎么办?这是最难的工程问题。
- 备份责任转移到你身上:云服务替你做了备份,本地优先要你自己想着备份(所以我在产品里内置了自动备份)。
- 初始体验更重:不像 SaaS 注册即用,你可能要配置一下同步目录。
冲突处理我采用的是「最后写入 + 保留历史版本」的务实策略:不追求无冲突的 CRDT 完美方案,而是让每次修改都留下可回溯的版本,冲突时让用户自己选。对个人数据来说,「能找回」比「永不冲突」更重要。
我的家庭数据管家是怎么搭的
我把这套原则落进了一个叫「哇哦.exe」的桌面应用,架构大概是:
- 本地数据库为主:所有数据先写本地(SQLite / 文件),界面永远读本地,秒开;
- 同步是可选模块:走自建的小服务或网盘目录,同步失败不影响本地使用;
- 重活放后台进程:媒体扫描、去重、生成缩略图在独立的 utilityProcess 里跑,不卡界面;
- 一切都能导出:照片、笔记、足迹都能导出成标准格式,不做数据绑架。
一个具体细节:媒体库扫描几万张照片时,如果放在主进程做,界面直接假死。把它扔到子进程后,界面全程可操作 —— 这就是「本地」和「好用」不矛盾的关键。
什么人适合,什么人不适合
适合你,如果:
- 你重视照片、笔记、足迹这类「陪你很多年」的数据;
- 你有多台设备,希望数据在自己手里也能同步;
- 你愿意为「数据主权」付一点点配置成本。
不适合你,如果:
- 你需要和很多人实时协作同一个文档;
- 你完全不想管备份,只想注册即用;
- 你的数据量小到「丢了也无所谓」。
这不是宗教,是取舍。我选择本地优先,是因为我做的工具是给「想长期拥有自己数据的人」用的。
如果你也在意数据主权,欢迎来聊聊你理想中的个人数据工具长什么样。具体项目可以看我的项目页,实践视频在 B站搜 codevtool、抖音搜 codevtool334。