Back

本地优先软件开发初学者指南

本地优先软件开发初学者指南

您可能遇到过这种情况:在应用保存一个简单笔记时等待加载动画,或者因为网络中断而无法访问您的工作。如果您的 Web 应用能够即时运行、离线工作,并在连接时无缝同步,会怎么样?这就是本地优先软件开发的承诺。

本指南介绍本地优先软件开发——一种数据主要存储在您设备上的范式,同步在后台进行,应用变得更快、更有韧性且更注重隐私。我们将探讨核心优势,解决主要挑战,并帮助您理解何时使用(以及何时不使用)这种方法。

核心要点

  • 本地优先将主要数据存储在客户端,在后台同步以实现即时性能和离线功能
  • 现代浏览器存储限制(千兆字节 vs 兆字节)和新 API 如 OPFS 使本地优先变得实用
  • 优势包括零延迟交互、真正的离线支持、简化的状态管理和更好的隐私保护
  • 主要挑战是同步复杂性、冲突解决和分布式客户端的模式迁移
  • 最适合生产力应用、创意工具和个人数据;不太适合金融系统或实时库存
  • 在添加同步功能之前,从简单的仅本地功能开始

什么是本地优先软件开发?

本地优先软件开发将数据的主要副本放在客户端设备上,而不是远程服务器上。您的应用不是通过网络发送每个读写操作,而是在本地数据库中存储和操作数据。同步在后台进行,确保所有设备最终达到一致状态。

这与”离线优先”开发不同,后者主要关注优雅地处理网络故障。本地优先更进一步,使客户端成为主要数据存储,将服务器视为备份或同步机制,而不是真实数据源。

这个概念通过 2019 年的 Ink & Switch 论文获得了关注,该论文定义了本地优先软件的七个理想:

  • 无加载动画(即时响应)
  • 您的工作不会被困在一个设备上
  • 网络是可选的
  • 与同伴无缝协作
  • 长期数据保存
  • 默认安全和隐私
  • 用户所有权和控制权

为什么本地优先开发正在获得关注

技术推动因素

现代浏览器已经移除了曾经使本地优先不切实际的障碍:

扩展的存储限制:浏览器存储已从兆字节增长到千兆字节。Chrome 现在允许最多 80% 的可用磁盘空间,Firefox 允许 10% 的磁盘大小,甚至 Safari 在 iOS 上也支持约 1GB 每个源。

新的存储 API:Origin Private File System (OPFS) 在浏览器中提供接近原生的文件 I/O 性能,使得直接在 Web 应用中嵌入强大的数据库引擎成为可能。

WebAssembly 性能WebAssembly 允许数据库引擎和复杂算法在浏览器中以接近原生的速度运行,尽管它仍然需要 JavaScript 来访问存储。

更好的工具:像 RxDBYjsTinyBase 这样的库已经成熟,为本地优先开发提供了生产就绪的解决方案。

用户期望

用户越来越期望即时响应和离线功能。正如 Martin Kleppmann 所说,“另一台计算机的可用性永远不应该阻止您工作。“这种期望推动了本地优先架构在 Linear、Figma 和 Obsidian 等流行应用中的采用。

本地优先架构的核心优势

对用户而言

即时性能:操作在毫秒内完成,而不是数百毫秒。基本操作无需加载动画。

真正的离线功能:无需互联网访问即可获得完整功能。重新连接时更改会自动同步。

数据所有权:用户控制他们的数据。数据存储在他们的设备上,减少对云提供商的依赖。

隐私设计:敏感数据可以保留在设备上或在同步前加密,降低泄露风险。

对开发者而言

简化的状态管理:本地数据库成为您的单一真实来源。您可能不需要 Redux 或类似的状态管理库。

降低后端复杂性:您通常只需要一个同步端点,而不是数十个 API 端点。服务器专注于冲突解决和数据存储,而不是业务逻辑。

更好的可扩展性:服务器处理定期同步操作而不是持续请求。这种”随数据扩展,而非负载”的方法可以显著降低基础设施成本。

默认实时:可观察查询和响应式模式使实时更新变得自然,而不是事后考虑。

本地优先开发的关键挑战

数据同步复杂性

同步是最困难的部分。当设备离线工作时,数据不可避免地会分歧。您有两种主要方法:

  1. 捆绑解决方案:像 Firebase 这样的工具提供即开即用的同步,但会将您锁定在他们的生态系统中。
  2. 自定义同步:像 RxDB 这样的库让您在现有基础设施上实现同步,但需要更多开发工作。

冲突解决

当多个用户离线编辑相同数据时,会产生冲突。常见策略包括:

  • 最后写入获胜(简单但可能丢失数据)
  • 自定义合并函数(灵活但复杂)
  • AutomergeYjs 这样的 CRDT(数学上可靠但有权衡)

模式迁移

与您控制的服务器数据库不同,客户端数据库存在于数千个设备上。迁移必须优雅地处理多个模式版本,因为用户在不同时间更新。

存储限制

虽然浏览器存储已经扩展,但它不是无限的。本地优先最适合用户范围的数据(最多几千兆字节),而不是大规模数据集。Safari 在 7 天不活动后仍可能清除数据。

安全考虑

客户端设备上的数据本质上不如服务器上的数据安全。加密有帮助,但您必须仔细设计访问控制并考虑设备被攻击的场景。

何时使用本地优先(何时不使用)

适合的场景

  • 生产力应用:笔记、任务管理、文档编辑
  • 创意工具:设计软件、代码编辑器、音乐制作
  • 现场应用:在低连接环境中使用的应用
  • 个人数据应用:日记、个人理财、健康追踪

不适合的场景

  • 金融交易:需要即时一致性的银行、支付
  • 库存系统:跨位置的实时库存水平
  • 社交网络:具有复杂权限的大规模共享数据集
  • 分析平台:聚合来自数百万用户的数据

开始本地优先开发

选择您的工具

本地优先生态系统为不同需求提供各种工具:

存储SQLite(通过 Expo SQLite)、IndexedDB、OPFS

同步和状态RxDBTinyBasePrismaLegend-State

冲突解决YjsAutomerge、自定义合并函数

框架JazzLiveStoreInstant

从简单开始

在添加同步之前,从仅本地功能开始。这有助于您理解模式,而无需分布式系统的复杂性。

为最终一致性设计

接受不同设备可能暂时看到不同数据的事实。设计您的 UI 和业务逻辑来优雅地处理这种情况。

规划迁移

设计您的模式时考虑演进。从第一天开始就对您的数据结构进行版本控制并规划迁移路径。

本地优先软件开发的未来

本地优先代表了我们构建应用程序方式的根本转变。随着浏览器功能的扩展和工具的成熟,我们正朝着一个即时、离线功能应用成为常态而非例外的世界迈进。

就像用户学会期待实时更新而不是页面刷新一样,他们很快就会期待即时工作和离线的应用。今天掌握本地优先模式的开发者将构建明天用户需要的应用。

结论

本地优先软件开发提供了引人注目的优势:即时性能、离线功能和用户对数据的控制。虽然它引入了同步复杂性和冲突解决等挑战,但现代工具和浏览器功能使其变得越来越实用。

关键是理解本地优先何时适合您的用例。对于处理用户生成内容、创意工作或生产力任务的应用,本地优先可以提供卓越的用户体验。对于需要即时全局一致性或大规模共享数据集的系统,传统架构可能仍然更可取。

当您探索本地优先开发时,请记住这不是全有或全无的选择。许多成功的应用混合了本地优先和云优先方法,在合适的地方使用每种方法。

今天就开始尝试本地优先开发。选择一个简单的项目——也许是笔记应用或任务管理器——并尝试首先使用本地存储来实现它。一旦您体验到即时性能和离线功能,您就会理解为什么开发者对这种范式转变感到兴奋。

对于实践学习,探索 Local-First Web 社区资源,加入 Discord 社区,或深入了解 RxDB、Yjs 或 TinyBase 等工具的教程。Web 开发的未来是本地优先——今天就开始构建它。

常见问题

离线优先专注于优雅地处理网络故障,通常使用缓存策略。本地优先使客户端设备成为主要数据存储,服务器充当同步机制而不是真实数据源。本地优先应用在设计上就能完全离线工作,而不仅仅是作为后备方案。

现代浏览器支持存储千兆字节的数据。Chrome 允许最多 80% 的可用磁盘空间,Firefox 允许 10% 的磁盘大小,Safari 在 iOS 上支持约 1GB。然而,实际限制取决于设备存储和用户期望。大多数本地优先应用最适合用户范围的数据,最多几千兆字节。

这会创建一个冲突,需要在设备同步时解决。常见方法包括最后写入获胜(简单但可能丢失数据)、智能组合更改的自定义合并函数,或使用数学上保证可合并操作的 CRDT(无冲突复制数据类型)。最佳方法取决于您的数据结构和用户需求。

是的,许多本地优先库支持自定义同步端点。像 RxDB 这样的工具让您通过添加用于拉取更改和推送更新的端点在现有数据库之上实现复制。这比即开即用的解决方案需要更多开发,但避免了供应商锁定。

本地优先可以是安全的,但需要仔细设计。客户端设备上的数据比服务器上的更容易受到攻击,因此要为敏感数据实现加密,为同步使用安全认证,并规划设备被攻击的场景。考虑您的安全要求是否允许客户端数据存储。

Listen to your bugs 🧘, with OpenReplay

See how users use your app and resolve issues fast.
Loved by thousands of developers