当前位置:首页 > 科技  > 软件

Figma 是如何做协同编辑的?

来源: 责编: 时间:2024-01-15 09:20:05 334观看
导读大家好,我是前端西瓜哥。我一直对图形编辑器如何做多人协同编辑很感兴趣,最近读了 Figma 前 CTO Evan Wallace 的文章《How Figma’s multiplayer technology works》,很有收获,于是写了这篇笔记。我建议读者直接阅读原文

Yeo28资讯网——每日最新资讯28at.com

大家好,我是前端西瓜哥。Yeo28资讯网——每日最新资讯28at.com

我一直对图形编辑器如何做多人协同编辑很感兴趣,最近读了 Figma 前 CTO Evan Wallace 的文章《How Figma’s multiplayer technology works》,很有收获,于是写了这篇笔记。Yeo28资讯网——每日最新资讯28at.com

我建议读者直接阅读原文,里面还有动图。Yeo28资讯网——每日最新资讯28at.com

https://madebyevan.com/figma/how-figmas-multiplayer-technology-works/Yeo28资讯网——每日最新资讯28at.com

参考 CRDT

协同编辑,需要用到数据一致性算法,目前成熟的算法有 OT 和 CRDT。Yeo28资讯网——每日最新资讯28at.com

Figma 没用 OT,太复杂,尤其是当离线数据本地缓存了很久才提交时,会进行复杂的 OT 算法计算,产生组合爆炸问题。Yeo28资讯网——每日最新资讯28at.com

CRDT,也有一定复杂度,而且是去中心的,Figma 还是需要一个中心服务实现鉴权功能。Yeo28资讯网——每日最新资讯28at.com

OT 和 CRDT 更多是针对富文本编辑的,而 Figma 是设计工具,作者认为没有必要引入这些复杂的东西,这样会让项目难以维护。Yeo28资讯网——每日最新资讯28at.com

Figma 最终选择借鉴 CRDT 的思想,自己实现一套协同系统。Yeo28资讯网——每日最新资讯28at.com

这里我比较赞同,我永远认为 “不要过早扩展”,能简单就不要复杂。Yeo28资讯网——每日最新资讯28at.com

因为一些后期不一定会用到的功能,强行做了更复杂的抽象和扩展,导致功能开发的心智负担过重,当发现这些后期功能不需要,并且要扩展另一个方向的一套功能时,原本抽象的设计变得毫无意义,且一切都积重难返,最后的结果只能是屎上雕花了。Yeo28资讯网——每日最新资讯28at.com

冲突处理

Figma 的设计文件的数据是一棵图形树,图形之间可能会有父子关系,比如一个 group 下有一个 rectangle,形成多层的树结构。协同编辑操作的对象就是这么一棵树。Yeo28资讯网——每日最新资讯28at.com

Figma 协同操作的最小原子是 对象的属性。Yeo28资讯网——每日最新资讯28at.com

修改同一个对象的不同属性没有冲突问题。Yeo28资讯网——每日最新资讯28at.com

多个用户同时修改同一个对象的相同属性时,最晚提交到服务端的值会覆盖其他用户的值,包括文本内容。Yeo28资讯网——每日最新资讯28at.com

假设一个属性的值是 B,一个用户修改为 AB,另一个用户修改为 BC,最终同步后,他们不会得到 ABC,只会是 AB ,或者 BC,看谁最晚提交。Yeo28资讯网——每日最新资讯28at.com

这个其实在大多协同表格应用也是类似的,单元格的内容也是最后提交者优胜,只有富文本文档才要求得到 ABC。Yeo28资讯网——每日最新资讯28at.com

处理闪烁现象

首先要明确 Figma 协同编辑的基本要求:Yeo28资讯网——每日最新资讯28at.com

  • 可以本地立即修改,而不是提交后再更新,这是为了有丝滑的用户体验,同时也能支持离线编辑能力;
  • 使用中心服务,而不是去中性化(说你呢 CRDT),Figma 的服务端会维护图形树,作为最终的权威,并负责修正用户提交的数据。

当多个用户同时修改同一个对象属性时,服务端返回的有冲突的属性值如果立即给对象应用上,可能会有 “闪烁” 现象。Yeo28资讯网——每日最新资讯28at.com

是这么一个场景,在同一时间,用户 A 将图形改成红色(本地改成红色然后提交到服务器),用户 B 改成黄色,用户 B 比用户 A 更早提交到服务器。Yeo28资讯网——每日最新资讯28at.com

对于用户 A,他会先看到颜色从红色变成黄色,黄色再变成红色,这种不期望的 “闪烁” 现象。Yeo28资讯网——每日最新资讯28at.com

解决方式是,用户 A 提交将颜色改成红色的操作,要等待服务端确认。在等待服务端确认期间,如果收到其他用户修改同一个属性的操作(用户 B 改成黄色),会把这个改动 丢弃。Yeo28资讯网——每日最新资讯28at.com

之后用户 A 收到服务端的确认消息后,如果此时有个用户 C 修改图形为紫色的操作同步过来,就会走正常的流程,将图形改成紫色。Yeo28资讯网——每日最新资讯28at.com

创建与删除

创建类似前面的做法,也是最后写入者优胜。(没理解)Yeo28资讯网——每日最新资讯28at.com

对于删除操作,Figma 服务器不会保存被删除的数据,这么做是为了防止文档大小持续增长。Yeo28资讯网——每日最新资讯28at.com

被删除的数据由进行删除操作的客户端负责,该客户端可通过 undo(撤销)恢复。Yeo28资讯网——每日最新资讯28at.com

系统需要保证 id 的一致性。Yeo28资讯网——每日最新资讯28at.com

做法是给每个客户端分配一个唯一 id,将其作为新创建对象 id 的一部分。这样两个客户端就不会生成相同的对象 id 了。(这有点像雪花算法)Yeo28资讯网——每日最新资讯28at.com

更改对象的父元素

修改对象的位置是 Figma 系统中最复杂的部分。Yeo28资讯网——每日最新资讯28at.com

其复杂度来自移动一个对象到另一个父节点操作。需要做到:Yeo28资讯网——每日最新资讯28at.com

  • 该移动操作不和该对象的其他无关属性冲突;
  • 并发的两个操作不会导致一个对象同时在多个父元素下。

很多做法是 “删除+重新创建” 表示对象的移动,但这会导致 id 的改变,对 Figma 并不合适。Yeo28资讯网——每日最新资讯28at.com

Figma 最后选择给对象加一个属性,指向它的父节点。这样 id 得以保持不变,多个用户同时进行操作只是在改这个属性,也有效避免了副本的出现。Yeo28资讯网——每日最新资讯28at.com

副本指的是,两个用户同时分别把一个图形放到不同的父节点上,如果用的是修改 children 数组的方式,就会导致两个父节点都挂着同一个图形的引用。Yeo28资讯网——每日最新资讯28at.com

然后还有一个 “环” 的问题,假设 B 和 C 是兄弟节点,一个用户将 B 放到 C 下,另一个用户把 C 放到 B 下,就会产生一个环。Yeo28资讯网——每日最新资讯28at.com

解决方法是,最先改变父子关系,会作为最终状态。假设用户 1 将 C 放到 B 下的操作先到服务器,服务器会应用它。此时服务器收到用户 2 把  B 放到 C 下的同步信息,服务器会将其驳回,带上真正的父节点 id。Yeo28资讯网——每日最新资讯28at.com

在驳回前,用户 2 其实收到了用户 1 的操作,客户端此时会将 A 和 B 临时形成环,然后移出图形树,接着驳回的信息回来,客户端就能确定父节点,然后恢复到图形树中。Yeo28资讯网——每日最新资讯28at.com

该方法并不是非常好,因为图形消失了一段时间,但方案比较简单,且这种场景非常罕见,Figma 不打算用更复杂的方案。Yeo28资讯网——每日最新资讯28at.com

顺序一致性

如果多个用户同时修改一个节点下的兄弟节点的位置,如何保证它们的最终顺序是一致的?Yeo28资讯网——每日最新资讯28at.com

Figma 使用了 “Fractional Indexing”(小数索引) 技术。Yeo28资讯网——每日最新资讯28at.com

兄弟节点会分配一个大于等于 0,小于 1 的小数索引值。Yeo28资讯网——每日最新资讯28at.com

插入新的节点,会取于它相邻的两个节点的索引值的中间位置,比如要在索引为 0.3 和 0.4 的中间插入新节点,这个节点的索引值会标记为 0.35。Yeo28资讯网——每日最新资讯28at.com

如果出现索引值相同的情况,服务端会进行纠正,把更晚提交的新节点的索引往后移动一点。Yeo28资讯网——每日最新资讯28at.com

实现撤销(undo)

单机的 undo,是将状态会恢复到上一个时间点,如果不加以改变,换成多人协同,就会导致当前用户的操作在其他用户撤销时被覆盖。Yeo28资讯网——每日最新资讯28at.com

Figma 团队总结了一个重要的准则:撤销后复制了一些东西,然后重做到当前位置,文档不应该被改变。Yeo28资讯网——每日最新资讯28at.com

Figma 的做法是 改历史记录。Yeo28资讯网——每日最新资讯28at.com

Figma 会在用户撤销的时候修改重做历史,以及在重做的时候修改撤销历史。Yeo28资讯网——每日最新资讯28at.com

用户 A 和用户 B 都打开一张图纸,其中一个图形原来是红色。用户 A 将其更换为蓝色,同步,此时双方都看到图形是蓝色。Yeo28资讯网——每日最新资讯28at.com

此时用户 B 又将图形改成黄色,同步,此时双方都是黄色的。。Yeo28资讯网——每日最新资讯28at.com

用户 A 进行撤销操作,撤销为红色(因为撤销栈记录的是红变蓝),此时重做栈的命令对象跑到重做栈,本来应该是蓝变红,但是 最新的文档状态是黄色,所以这里强行把替换为黄变红。Yeo28资讯网——每日最新资讯28at.com

这样历史记忆就被篡改了,可以保证重做后能回到最新状态。Yeo28资讯网——每日最新资讯28at.com

对于用户 B,则不需要修改,因为他的历史记录是就是红变黄(黄是最终状态)。Yeo28资讯网——每日最新资讯28at.com

要点

最后是作者的一些心得:Yeo28资讯网——每日最新资讯28at.com

  • CRDT 的文献很有参考价值,即使你不打算做非中心化协同;
  • 可视化编辑器的协同编辑并没有想象中难做;
  • 在开做之前先调研并实现原型是非常有价值的。

结尾

文章看下来,大概有一些图形编辑器如何做协同编辑的概念了,以后有机会实践一下。Yeo28资讯网——每日最新资讯28at.com

其中一点我是非常赞同的,就是方案能简单就不要复杂,我不是很喜欢一些高度抽象的东西,代码是写给人看的,只是顺便让机器执行而已。Yeo28资讯网——每日最新资讯28at.com

本文链接:http://www.28at.com/showinfo-26-60932-0.htmlFigma 是如何做协同编辑的?

声明:本网页内容旨在传播知识,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。邮件:2376512515@qq.com

上一篇: Python实战:用 Python 制作井字棋小游戏

下一篇: 如何在函数式编程中处理可变状态和副作用?

标签:
  • 热门焦点
  • Redmi Pad评测:红米充满野心的一次尝试

    从Note系列到K系列,从蓝牙耳机到笔记本电脑,红米不知不觉之间也已经形成了自己颇有竞争力的产品体系,在中端和次旗舰市场上甚至要比小米新机的表现来得更好,正所谓“大丈夫生居
  • 7月安卓手机性能榜:红魔8S Pro再夺榜首

    7月份的手机市场风平浪静,除了红魔和努比亚带来了两款搭载骁龙8Gen2领先版处理器的新机之外,别的也想不到有什么新品了,这也正常,通常6月7月都是手机厂商修整的时间,进入8月份之
  • 2023年Q2用户偏好榜:12+256G版本成新主流

    3月份的性能榜、性价比榜和好评榜之后,就要轮到2023年的第二季度偏好榜了,上半年的新机潮已经过去,最明显的肯定就是大内存和存储的机型了,另外部分中端机也取消了屏幕塑料支架
  • iPhone卖不动了!苹果股价创年内最大日跌幅:市值一夜蒸发万亿元

    8月5日消息,今天凌晨美股三大指数高开低走集体收跌,道指跌0.41%;纳指跌0.36%;标普500指数跌0.52%。热门科技股也都变化极大,其中苹果报181.99美元,跌4.8%,创
  • 虚拟键盘 API 的妙用

    你是否在遇到过这样的问题:移动设备上有一个固定元素,当激活虚拟键盘时,该元素被隐藏在了键盘下方?多年来,这一直是 Web 上的默认行为,在本文中,我们将探讨这个问题、为什么会发生
  • JVM优化:实战OutOfMemoryError异常

    一、Java堆溢出堆内存中主要存放对象、数组等,只要不断地创建这些对象,并且保证 GC Roots 到对象之间有可达路径来避免垃 圾收集回收机制清除这些对象,当这些对象所占空间超过
  • 自研Exynos回归!三星Galaxy S24系列将提供Exynos和骁龙双版本

    年初,全新的三星Galaxy S23系列发布,包含Galaxy S23、Galaxy S23+和Galaxy S23 Ultra三个版本,全系搭载超频版骁龙8 Gen 2,虽同样采用台积电4nm工艺制
  • 三星显示已开始为AR设备研发硅基LED微显示屏

    7月18日消息,据外媒报道,随着苹果首款头显产品Vision Pro在6月份正式推出,AR/VR/MR等头显产品也就将成为各大公司下一个重要的竞争领域,对显示屏这一关
  • iQOO Neo8 Pro即将开售:到手价3099元起 安卓性能最强旗舰

    5月23日,iQOO如期举行了新品发布会,全新的iQOO Neo8系列也正式与大家见面,包含iQOO Neo8和iQOO Neo8 Pro两个版本,其中标准版搭载高通骁龙8+,而Pro版更
Top