文档技术连载 2/4:语雀电子表格的自研路

2020/7/13 11:09:38

本文主要是介绍文档技术连载 2/4:语雀电子表格的自研路,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

前端早早聊大会,前端成长的新起点,与掘金联合举办。

加微信 codingdreamer 进大会专属编辑器/文档技术群


第十二届|前端可视化专场,7-18 直播,10 位讲师(蚂蚁金服/阿里云等),大会报名地址

本文是第九届 - 在线文档,前端早早聊第 61 场,来自语雀团队高级前端技术专家 - 遇春的分享讲稿简要整理版(完整版含演示请看录播视频和 PPT):


前端搞文档 | 遇春 - 语雀电子表格自研之路

自我介绍

我叫赵勇,花名叫遇春,2009 年加入阿里巴巴淘宝 UED,2015 年加入到蚂蚁体验技术部,目前在语雀团队。

背景介绍

语雀是蚂蚁金服体验技术部的一个创新产品,目前已经在商业化运作。面向个人和组织提供知识创作、组织、交流服务。如果你或者你的团队有知识管理的需要,可以尝试使用语雀。语雀一直很看中创作体验,所以我们在编辑器这个领域一直持续的投入研发,不断迭代,今天要介绍的就是我们自主研发的在线电子表格。

在准备这个分享的时候,我特意去看了下代码的第一次提交记录,是去年的 5 月 29 日,刚好一年的时间,在分享的前面,先给大家介绍下语雀电子表格这一年的研发时间表。

2019年
  • 5 月:立项。
  • 8 月:Beta 版上线,具备基本的行列操作、基本样式、合并单元格、筛选排序,支持插入链接、图片、附件、checkbox、下拉选项等。
  • 9 月:导入功能,多 Sheet,公式,统计栏,增加日期、货币、时间类型。
  • 10 月:格式刷,图片复制粘贴,支持附件预览,边框功能上线。
  • 11 月:导出功能上线,实时协同上线,单元格保护功能。
  • 12 月:图表功能上线,选择性粘贴。
2020年
  • 1~3 月:稳定性,兼容性,性能,体验优化。
  • 4 月:条件格式,下拉选项优化。
  • 5 月:表格模版,筛选优化,颜色筛选。

有兴趣的同学可以到语雀的更新日志里了解更多详情。

经过一年的研发,语雀已经能够满足 80~90% 普通 Excel 用户的功能需求,以下是目前我们的功能集,接下来我们会控制新功能的上线节奏,会专门针对已有功能做深度优化,我们希望这些最基础的功能,能够给用户带来喜悦。

通过上述介绍,希望大家能对语雀目前的状态有一个整体的了解。

接下来会分三部分介绍语雀的自研历程:Why、How、What。

在语雀团队以及体验技术部,不管做什么,我们都会多问自己几个为什么,想透为什么做往往比去思考怎么做更重要。

  • Why:介绍我们在做表格前期的思考。
  • How:讲的是怎么做,以及研发过程中的一些方法和技术选型。
  • What: 谈一谈关于自研的一些心得。

WHY

这一部分我会介绍两个问题:

  • 为什么做在线电子表格
  • 为什么选择自研

为什么做在线电子表格

电子表格起源

提到电子表格,大家可能最先想到的是 Excel,我们的一些用户在向我们咨询问题的时候也有的说“你们语雀的 Excel 做的怎么怎么样”,我觉得这是 Excel 这么多年来在大家心里形成了根深蒂固的影响,认为表格就是 Excel,但其实 Excel 并不是第一个电子表格软件。第一个电子表格要追溯到 1978 年,美国的一个大牛 Dan Bricklin,在大学实验室做的一款叫做 VisiCalc 的程序。

这是首次利用行列布局来完成数字的录入和计算的软件,虽然简单,但已经具备了如今电子表格最核心的行列模型,当时人们做生意都是用笔记在账本上,一条条记录,到了月底要做汇总对账,效率非常低,而且容易出错,一旦出错就得重头算,所以 VisiCalc 一面世就获得人们的喜爱。这款软件当时就是安装在苹果 2 代的个人电脑上。

就是靠这款软件,当时苹果电脑 2 代打开市场,大卖特卖,乔布斯当年接受采访时说电子表格促进了产业发展,VisiCalc 促成了苹果的成功。

电子表格关键历程

1985年

Excel 1.0 面世,这版 Excel 是微软专门为苹果开发的软件,后来盖茨觉得给人写软件不过瘾,就搞出来 Windows。这里面还有一段乔布斯和盖茨的一段恩怨故事。

1988年

求伯君在小黑屋里写了 14 个月开发出来的一个国产办公软件 WPS,为国内程序员所敬仰。

1993年

微软推出 Office 办公套件,将 Excel 捆绑进来,再后来就是 Excel 一骑绝尘,不断迭代,几乎没有对手。

2006年

出现了一个新鲜事物 Google Docs,所有程序员都看呆了,原来在网页上可以实现客户端办公软件的能力,这也一定程度掀起了前端行业的逐步繁荣。

2007年

苹果开发了自己的电子表格 Numbers, 这是一款体验很棒的电子表格,不改苹果一贯的简单风格,但藏在里面的有非常强大的功能,目前还不支持在线协同。

2011年

微软开始关注在线办公体验,推出在线版的 Office 365, 在线版的 Excel 体验真的很一般。

2013年

Airtable 出现,人们开始意识到,原来的电子表格可以这么玩,这就是后面要说到底同构表。

2016年

国内才陆续出现在线电子表格的产品,其中 WPS、石墨在这块做的比较早,再后来腾讯和飞书等大厂也开始跟进。

从上述持续 40 几年的历史长河中,电子表格始终保持着旺盛的生命力,功能不断完善,从客户端软件走向线上,足以证明人们对数据处理的需求始终旺盛。

语雀与 DIKW 模型

再说回来,为什么语雀要做电子表格,这得从一个词来说起,那就是“知识”,知识怎么定义。

语雀的产品定位是云端知识库,我们内部一直有一个有意思的讨论就是:“什么是知识”,知识和数据之间又有什么关系,直到我们发现这个模型,早在 1888 年,就有人在思考这个问题,托马斯·斯特尔那斯·艾略特在一本《The Rock》书中思考过知识,智慧,咨询之间的关系,后来学者们逐步完善这样一个模型:DIKW 模型。

  • 数据层:数据是最原始的素材,这一层的关键任务是记录,数据本身也具备信息属性,但反应的更多的是过去,比如杭州市 2019 年每天的气温、湿度、降雨等数据。
  • 信息层:从数据层中提炼一些浓度更高的信息,或者根据数据的关系进行统计分析,发现一些规律性,比如杭州的年平均气温、几月份最热、几月份最舒服,这些信息已经足够精炼,也已经具备了一定参考价值。
  • 知识层:通常信息层已经具备生活和生产的指导性,但信息层的信息还比较零碎,知识层则是结合更多维度的信息,有针对性,有目的性的将零碎的信息进行归类、连接,产出一些更全面的信息,比如把全球近 100 年的气象数据进行分析,就会发现地球温度在上升,于是结合数据之间的关系,发现了温室效应,经过验证发现,二氧化碳是造成温室效应的原因,这种知识的价值就更大了,所以:知识就是来源于生活,被大众认可,最终能够帮助人们作出决策的东西。
  • 智慧层:随着对知识的运用,人们通过收集到的数据就可以预测未来会怎样发展,这就是智慧。

在这个模型中,可以很清楚的看到,要形成知识,人们首先要从数据处理中产出信息,在这一步表格就发挥了非常重要的作用。文档则是从信息到知识的进一步整理,所以,作为要打造专业的云端知识库,我们在整个知识的产生过程中,自然不能缺失数据处理这一环。

为什么自研

为什么选择自研,我记得小米有品的一个营销负责人有一句话说的很好:“生活中 99% 的产品都值得被重新创造一次”。

作为电子表格这样一款几十年历史的产品,如何重新创造?Airtable 给出了他的答卷,它更像一个在线版的 Database。其实,语雀曾经也在集团内部推出过一版类似 Airtable 的同构表格,是基于 Spreadjs 来做的,发现用户并不是很买账这个新鲜事物,加上后续的一些变故,我们停止继续研发,因为总有一种手脚被束缚的感觉。

2018 年,我们开启了全面自研,先是 kindEditor 的作者隆昊老师的加盟, 语雀的文档编辑器开始全面自研,上线后,性能上有了明显的提升,而且后期的研发和维护效率非常高。用户提的很多问题我们都能第一时间响应,快速解决,这次自研给我们团队带来了很大的信心,我个人也是从文档表格开始进入编辑器领域。

2019 年 5 月我们决定重启表格的研发,抛开 Spreadjs, 全面自研,自研给我们带来的底层的可控性,拓展性,而且从长期看,自研的综合成本效率都很优,选择自研你要慎重的考虑以下几个因素:模型、体验、性能、研发、维护、业务等各种要素。

  • 模型:数据模型是业务发展的根本,也是所有功能实现的基础,掌握数据模型的设计,才有可能更好的满足未来的业务和功能需要,自研可以完全掌控模型的设计。
  • 体验:广义的体验包含很多方面,包括性能、服务,这里主要指狭义的体验:交互体验,自研可以更大程度的按照业务的需要来设计体验,技术实现更加融为一体,而不是在别人的功能上打补丁。
  • 性能:掌握模型就可以在关键性能的地方通过数据结构的优化来解决,架构也可以做针对性的设计。
  • 研发:从长期来看,自研的研发成本反而更低。
  • 维护:由于对底层掌控性,遇到问题修复起来更快。也不会遇到因为底层的缺陷而无法修复的问题。
  • 业务:自研可以根据业务需要来设计模型。更有拓展性。

HOW

  • 用了什么技术
  • 一些技术方案选型的案例

用了什么技术

首先是表格的前端架构图,这是一个非常经典的 MVC 架构,Model 层处理数据,View 层有渲染部分以及工具栏和面板等 UI 部分,渲染部分采用原生的 Canvas 进行绘制,UI 层用了 React,组件库是 antd,图表用了 AntV,UI 层的事件收敛到 Control 层,Handler 去处理事件的参数以及准入规则,然后就交给 Command 去执行数据操作,Command 里会有一个 history 对象去维护一条条命令,包含执行这条命令的参数以及执行中需要携带的快照数据,方便撤销并通过 WebSocket 协同服务将命令同步到其他用户端,架构很简单,在选择技术方案上,语雀一直追求实用与简单。

同构还是异构

我想分享的第一个选型是在设计模型时需要考虑的问题,关于产品的选型,也就是前面大家听到的,同构表还是异构表。

  • 同构表:每一列数据具备相同的数据结构,比如文本,日期时间,这些在列头定义,一旦定义好,整列的数据都会按这个数据结构来处理,所以他的数据格式属性只需要定义在列头即可。
  • 异构表:每一个单元格都可以设置自己的数据格式,整个表格更像一个行列布局的画布,每个单元格可以设置公式,会更加灵活。

可以看出,他们各自有自己的优势和劣势,在数据处理上的实现差异也特别大。

该如何选择,我们最终还是去看用户的需求,会发现两类非常经典的场景,一种是信息结构化,一种是数据处理,这两种场景都非常重要。

数据处理不用多说了,肯定要满足。那信息结构化是什么,就是利用表格天然的行列布局,让信息布局更合理,更容易理解。而信息结构化本身也是前面我们提到的,是知识形成过程中重要的环节,有时候结构化布局也是知识的展现形态的一部分。有些信息必须通过表格才能更好的展现,比如元素周期表,而我们知道同构表是没法做合并单元格的,在信息布局能力上存在较大的缺陷,所以我们最终选择了异构表。

多人协同编辑

多人实时协同一直是编辑领域最大的难题,表格编辑也同样会遇到,而且会更加复杂,我们先从多人协同的模型说起。

两个人同时基于一条基线开始编辑,当这两条指令 O1、O2 传递到对方那里的时候,要进行变换(OT),这里是最细颗粒的 OP,而通常对于表格操作,比如移动行列,可能会有上千条 OP, 如果刚好另外一个用户也做了类似的批量操作,那么瞬间产生的大量 OP 传递到服务端,服务端需要花费很长时间来做 OP 转换,这就是导致响应延迟,那么用户会进一步产生 OP,造成更多的计算和延迟,形成拥塞。

对于表格的操作,我们可以看这张图。

一个大的数据对象,执行一条 Command,产生数条 Op,如果同步 Op 对性能有太大的挑战,是否可以直接同步Command?我们可以对比看两种模型的差异性。

通过对比两种方案我们最终选择了基于 Command 来做数据同步,每一条 Command 会携带这条命令需要的参数值,传递到其他端,服务端不需要做操作变换,客户端收到 Command 后会直接运行,整个过程非常快,通常一条指令从发出到接收到指令可以在 100ms 以内甚至更快完成,我认为快速将指令同步到各端,是减少冲突的最好办法。

我们知道,通常单元格编辑的指令并不会存在冲突,只有在做行列位置变换或者增减行列时才有可能出现冲突,那么我们需要考虑的问题是:在 100ms 以内同时操作行列的概率有多大,从实际场景来看,这个概率非常小。我们再配合一些冲突后禁止撤销等策略来防止数据的混乱。最终我们采用了一个权衡的方案,同步 Command。从使用效果看,已经能够满足大多数的协同场景。

单元格数量上限

做电子表格过程中会遇到很多极限边界,比如最大的可计算的数,日期的可识别范围等,接下来我们说说表格最大能支持多少单元格数量。

我们首先看看几个有明确限制的竞品,Google 明确支持 500w 单元格,超过就会报警。飞书是 50w,腾讯文档是 25w。Google 是将数据存储在服务端,运算也在服务端,所以其实理论上可以支持更大的数量,所以看上去只是单元格数量上限的差异,却引来一个很重要的架构选型:数据运算在客户端还是服务端。但其实选择起来也不难,还是要回归业务本身,在线电子表格的大多数场景都不会有那么大的数据量,再基于两个考虑点:

  • 充分利用客户端计算资源
  • 保持架构简单

我们选择客户端计算,就是将数据一次性加载到客户端,在用户的浏览器中进行计算,那么这种模式下我们能支持到的最大单元格数量是多少呢?

我们做一个这样的计算,以最小的存储单元格,存储一个十位数的数值,这里只考虑存储值,如果再加上格式,样式,一个单元格大概需要 20~200 个字符,为了做本地的临时存储,我们采用了 localStorage,上限是 5M,(当然,有同学说可以使用 IndexedDB, 还是考虑简单原则,IndexedDB 的异步模型会使整个编程模型变复杂,能不用复杂的方案,我们尽量不用),利用 localStorage,可以支持的单元格数量上限是 25w(10000 行 25 列)。

在这个方案的基础上,我们做了再次压缩优化,最终可以做到 250w 单元格,当然这是在保证离线编辑时体验无损的场景,如果是网络环境好的时候,并且没有大量公式和样式的话,语雀表格可以支持更大量级。

我们看看在百万量级下的数据编辑性能效果。

百万表格操作.gif
百万表格操作.gif

复制粘贴的破损修复

在表格的操作中,经常会遇到复制粘贴的操作来从其他地方搬运数据过来,比如从网页,或者 Excel、Numbers 将数据迁到线上,复制和粘贴在解决局部或少量数据的时候是最高效的,而通常我们从这些地方复制出来的表格都会遇到一些奇怪的问题,那就是破损。

像上图这样的复制行为,剪切板里的 HTML 就会有奇怪的单元格 Td 或者 Tr 的丢失,对于表格来说,如果解析的时候缺少 Tr、Td,那么单元格的位置就容易解析错误,最终导致粘贴出来的数据错乱,可以看下面的动画。

表格修复_yuque.gif
表格修复_yuque.gif

语雀表格在还原各种复制粘贴中的破损时,表现的更为出色。

更多有趣的故事

除了上述的案例,我们还有很多研发中的小案例,里面包含着我们对产品的思考,对体验的认识,对技术的态度,时间关系不能全部展开。

欢迎大家尝试语雀,并给我们提出宝贵建议。

WHAT

最后一部分说一下自研中的心得,比较不成体系,不过却是真实感受,希望有自研打算的同学可以有些参考。

结尾

招聘时间

语雀目前完全自研的编辑器包括以下四款,我们欢迎更多对编辑器感兴趣的同学加入我们。

有兴趣的同学可以直接简历砸过来。

jobs@yuque.com

语雀,期待与你一起,提供更佳的创作体验,让知识等于财富。

本文使用 mdnice 排版



这篇关于文档技术连载 2/4:语雀电子表格的自研路的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


扫一扫关注最新编程教程