最近对 local-first 的软件设计多了一点关注,local-first 从本质上来说,并不是什么新的概念,早期的计算机软件可以说都是 local 的,也就是本地运行,我们所说的单机版软件。我在大学的时候,学的还是 MFC 的开发,那个时期基本都还是以本地软件为多数,不久就进入 web 时代,软件架构开始走向 web 架构,cs 架构越来越少。web 架构无疑是推动云计算发展的关键因素之一。大家有没有感觉到,最近几年又大有桌面软件兴起之势,各种应用除了提供移动 APP 版本,同时还提供 pc 的安装版本。也许这个世界本就是存在一些未知的因果轮回。
国内 local-first 并没有特别引起大家注意,在国外却是实实在在的有很多人在关注和实践。今天 local-first 并不只是一种软件架构或者产品设计方法,更像是一场运动,一场由部分软件开发者发起,希望通过 local-first 改变以 web 服务为中心,以云计算为中心,个人数据被掌控在软件服务提供商手中的局面。
local-first 这场运动的愿景是希望让软件同时提供离线和在线的能力,以及实现多端同步协同的能力,最终能够提升个人数据的安全性、隐私,让软件能够保持长期的可用性和对个人数据的掌控和归属。
从产品和技术指标维度看,一个软件如果符合 local-first,那么它需要满足以下特点:
这样看来,早期的计算机软件只是 local,而不是 local-first,所以通常称它们为单机版软件。web 应用几乎是 local-first 应用的对立面,这种对立不是指软件功能属性,而是技术架构上。local-first 的技术架构必然是以客户端为中心进行设计,服务端只是辅助提供同步,协作等方面的基础能力;而今天的 web 应用天然是以服务端为中心进行设计,数据在服务端、运算逻辑在服务端、UI 渲染在服务端,完完全全的轻客户端架构路线。所以,上文提到 web 架构是促进云计算的关键因素之一。
local-first 倡导的软件设计,是否适合所有类型的应用软件?显然是不行的。那些面向个人的,具有很强创作属性的应用软件更合适 local-first 的架构。文档应用,笔记应用,画图、设计类应用等等都属于创作类,其实微博、twitter也属于创作类,然而它们显然不是 local-first 的,我们可能创作了数万,甚至数十万条微博,但我们却不拥有这些微博数据,某一天我们也可能会完全失去这些数据,失去使用权,它们从这个世界上凭空消失掉,就像从来没有出现过一样。相反,一个电商应用可能就无法采用 local-first 架构,因为用户需要的是交易,而不是交易记录。内容创作软件的用户是创作者,这个群体在情感和工作性质上对 local-first 的诉求也更强烈。没有哪一个创作者一觉醒来的时候,希望看到自己辛辛苦苦创造的作品凭空消失了;同时,创作者们有着高度不确定性的工作环境,可能是野外、偏远山区、高铁上、飞机上,不确定的工作环境对软件离线使用有着明显的需求。程序员也是典型的内容创作者,我们通过编写代码来实现各种各样的作品。我们在编程的时候使用的软件工具基本都是 local-first 的,包括 IDE 和 git 。git 真的是一个非常 local-first 的软件,我们可以没有任何 git server,就可以在本地使用所有的 git 功能,然后随便部署一个 git 服务器,就可以实现本地代码的同步 + 协作;这真的是一个非常优秀的设计。有时候,我们根本不用过多的担心某个开发同学一不小心把 git server 上的代码仓库给删除掉了,因为几乎每个开发者电脑上都有一份代码。在 local-first 的软件产品中,Sqlite,CRDTs等基础技术将被重度使用。前不久,看到 sqlite 官方推出了 sqlite 的 wasm 项目,在当时我是非常的不能够理解 —— 将 sqlite 运行在浏览器中,给前端提供一个可以直接访问的数据库的意义在何处。普通的 web 架构应用,sqlite 运行在浏览器中的意义,我始终认为不大;但对于 local-first 应用来说,采用 sqlite 估计会是必选项。在进一步的思考一下,local-first 应用在将数据写入了本地的 sqlite,当需要考虑同步的时候,那又将如何把数据同步到服务端呢?当然,每个应用的开发者总有自己的一套方法或者代码实现这个功能。但我发现了一家公司叫 electric,他们致力于提供数据层面的基础设施,解决这个同步问题。Electric 是一家欧洲的初创公司,目前在种子轮中,他们的产品 ElectricSQL 提供的核心功能就是 “给 local-first 应用提供云端同步能力,不需要修改你的应用代码” ,引用他们官网的描述 “You develop local-first apps. We provide the cloud sync. Without changing your database or your code.” 。ElectricSQL 采用的是事务因果一致性模型,这和大多数分布式数据库采用某种共识算法(比如raft)实现的一致性是不同的。另外,这家公司一周只工作 4 天。
云计算,大家都已经非常的熟悉。性能越来越强的弹性计算服务(ECS、EC2 …) 让我们可以部署更复杂的应用计算逻辑,高性能的分布式存储、云原生数据库收集了这个世界每天产生的海量数据,遍布全球的云计算数据中心以及密集的 CDN 网络都在努力从覆盖层面触达服务更多的地方和人群。
云计算正在演变得越来越强大,正在悄无声息的为我们提供基础服务,就像水电煤一样,将会无处不在。前几年云计算刚刚兴起的时候,有很多的观点都认为云计算会让终端设备越来越轻量,大家只需要一个廉价、简单的终端设备就可以干所有的事情。然而现实并不是如此,最近我刚入手了一台 14 寸的 macbook pro,看那 cpu,gpu 的核心数都快赶上服务器,价格当然也是很感人。为什么会这样?说好的,云计算的发展会带来更轻、更廉价的终端呢?仔细想想,我认为至少有两方面的原因。其一,随着社会的发展,需求的变化,现代应用的绝对体验并不能完全靠云计算服务来解决,还存在一部分 gap 需要在客户端完成。比如:通过 Electron 构建的本地 APP 在大多数情况下都不如 Native APP 的体验流畅。其二,云实实在在的让应用开发变得更加简单,因此大量的新兴 APP 如雨后春笋一般出现,同时更多更复杂的功能被完成,这些应用或功能不管是直接运行在本地设备,还是浏览器中,都因为其又多又复杂,对终端设备的性能挑战是只增不减。从这个角度来看,云计算和终端设备是相互促进的关系,而不是此消彼长。Local-first 和云计算从表面上是存在理念上的冲突,Local-first 运动倡导的是让应用以客户端为中心进行设计,希望能够紧紧的将数据存储在本地,为自己所掌控,脱离云也能够正常运行。终端设备的性能以及围绕终端设备的技术在飞速的发展,会为 local-first 提供一定的基础条件。即便是如此,云的理念还是太美好了,似乎留给 local-first 的空间并不会太多。当然,未来应用哪怕都是 cloud-first,数据所有权问题永远都不会消失,永远都会是人们关注的焦点。我还是会 “由于自己使用的一个初创 APP 的破产,导致失去自己创作的内容而难以接受“。
如果有了好的点子、创意,何不尝试做一款 local-first 的应用产品呢?local-first 应用产品在初创阶段具备很多的优势,可以用最低的成本投入到市场中,连云服务器都不需要购买,这个时候的应用产品就等同于单机软件,随后再将服务器端功能迭代进去,提供更多更强大的互联网功能,完成商业收费。
参考:
https://www.inkandswitch.com/local-first/
https://electric-sql.com/blog/2022/05/20/relativity-causal-consistency