yjs

2025-02-04

前端

她说好想我。这在我局狭的一片草地上,可是一大把阳光,心底暖洋洋的。——送花的人走了

https://github.com/yjs/yjs

https://github.com/yjs/yjs

在构建实时协作应用时,我发现了一个非常强大的开源库——Yjs。它是一个高效、模块化的 CRDT(Conflict-free Replicated Data Type) 实现,专注于实现实时协作功能。Yjs 能够同步不同客户端的共享数据状态,即使在网络断开或冲突的情况下,所有更改都可以无缝合并,类似于 Google Docs 这样的多人协作体验。


什么是 Yjs?

Yjs 是一个基于 JavaScript 的实时协作引擎,支持在多个客户端之间共享数据同步。它通过 CRDT 技术来处理并发更新和冲突,使得用户在离线或网络不稳定的情况下依然可以正常操作,待网络恢复后自动完成数据同步。

Yjs 具有极高的性能优化和扩展性,可以集成到各种应用场景中,例如实时文本编辑器、协作画板、表单、项目管理工具等。


Yjs 的核心功能

  1. 实时协作
    支持多用户同时编辑共享数据。无论是文档、列表、地图还是自定义数据结构,Yjs 都能保持数据同步。

  2. 高效的 CRDT 实现
    Yjs 使用 CRDT 来管理分布式数据,保证所有客户端最终达成一致的状态,即使在有冲突或延迟的情况下。

  3. 模块化设计
    Yjs 提供了灵活的模块体系,可以与不同的网络协议(WebSocket、WebRTC、IndexedDB 等)集成,支持定制化的同步和存储策略。

  4. 离线支持
    支持离线编辑,用户的操作会在重新连接网络时自动同步到其他客户端。

  5. 轻量高效
    相比其他 CRDT 实现,Yjs 的内存和网络使用量非常低,适合大规模协作场景。


安装与快速使用

1. 安装

你可以通过 npm 或 yarn 安装 Yjs:

1
npm install yjs

或者:

1
yarn add yjs

2. 创建共享文档

以下是一个简单的示例,展示如何使用 Yjs 共享文本数据:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import * as Y from 'yjs'

// 创建一个共享文档
const ydoc = new Y.Doc()

// 创建一个共享文本类型
const ytext = ydoc.getText('sharedText')

// 添加事件监听器,监听内容变化
ytext.observe(event => {
console.log('文档内容已更新:', ytext.toString())
})

// 修改共享文本内容
ytext.insert(0, 'Hello, Yjs!')

3. 使用 WebSocket 同步

为了实现多个客户端之间的同步,Yjs 提供了与 WebSocket 协议的集成方案。你可以使用 y-websocket 模块快速配置同步:

1
2
3
4
5
6
7
8
9
import { WebsocketProvider } from 'y-websocket'

// 创建 WebSocket 提供器
const provider = new WebsocketProvider('wss://demos.yjs.dev', 'my-room', ydoc)

// 监听连接状态
provider.on('status', event => {
console.log('连接状态:', event.status) // "connected" 或 "disconnected"
})

通过这种方式,多个客户端可以实时同步共享数据。


核心数据类型

Yjs 提供了几种核心的数据类型,满足不同的协作需求:

  • Y.Text:支持富文本编辑和同步。
  • Y.Array:支持数组操作,适合列表、表格等数据结构。
  • Y.Map:键值对数据结构,适合存储配置或文档元数据。
  • Y.XmlFragment:适用于 XML/HTML 结构化文档的同步。

这些数据类型都支持事件监听和变更通知,方便开发者进行实时更新处理。


集成场景

1. 实时文本编辑器

Yjs 可以与富文本编辑器(如 Tiptap、ProseMirror、Quill)集成,实现多人实时编辑。通过 CRDT 技术,用户的操作不会因冲突而丢失。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import { Editor } from '@tiptap/core'
import StarterKit from '@tiptap/starter-kit'
import * as Y from 'yjs'
import { Collaboration } from '@tiptap/extension-collaboration'

const ydoc = new Y.Doc()
const editor = new Editor({
extensions: [
StarterKit,
Collaboration.configure({
document: ydoc,
}),
],
})

2. 协作画板

可以使用 Y.Array 或 Y.XmlFragment 实现实时协作的画板工具,用户在不同客户端上绘制的内容会同步更新。

3. 项目管理工具

支持任务列表、评论系统等多种协作功能,保证不同用户在同一项目中的实时同步。

4. 实时协作表单

在多人填写同一表单时,Yjs 可以确保数据一致性和同步。


存储与持久化

为了支持断线重连和离线编辑,Yjs 可以将数据持久化到本地存储。常用的存储模块包括:

  • y-indexeddb:将数据持久化到浏览器的 IndexedDB。

    1
    2
    3
    4
    5
    6
    import { IndexeddbPersistence } from 'y-indexeddb'

    const persistence = new IndexeddbPersistence('my-doc', ydoc)
    persistence.on('synced', () => {
    console.log('文档已同步到 IndexedDB')
    })
  • y-leveldb:适用于 Node.js 环境的持久化存储。


性能与扩展性

Yjs 通过优化 CRDT 数据结构和网络传输协议,实现了极高的性能。相比其他协作引擎,Yjs 的内存使用和带宽消耗更低,适合高并发、大规模用户协作的应用场景。

此外,Yjs 的模块化设计使其可以灵活集成不同的网络协议和存储后端,满足各种复杂场景的需求。


社区与生态

Yjs 拥有一个活跃的开源社区,提供了丰富的生态支持。以下是一些常用模块和工具:

  • y-websocket:WebSocket 同步模块
  • y-webrtc:基于 WebRTC 的点对点同步模块
  • y-indexeddb:浏览器端本地存储模块
  • y-docs:社区贡献的文档和示例

你可以通过 GitHub 提交 Issue 或 PR,与开发者和社区成员交流。


总结

Yjs 是构建实时协作应用的绝佳选择。它通过高效的 CRDT 实现,提供了稳定、可靠的同步功能。无论是文档编辑、画板工具,还是项目管理平台,Yjs 都能帮助开发者快速实现多人协作功能。如果你正在寻找一款高性能的协作引擎,Yjs 值得一试。

更多详情请访问 Yjs GitHub 项目官方文档