我最近在做一个web端的PPT项目,其中最重要的就是编辑器画布的技术选型
摆在面前的有两个选择:
- 一个是DOM+Position定位
- canvas引擎
坦白讲刚开始我是选择了canvas引擎这种方案,然后canvas引擎选择的时候leaferjs,当时思考的比较简单,canvas肯定比dom有性能优势,然后就开始了初步的尝试
但是很快就遇到了一些问题
- 复杂的状态管理canvas引擎的数据不容易被掌握
- canvas如果不用第三方引擎事情就会变的很复杂
- 如果用canvas现成的引擎,他的数据格式定死了,不一定能够满足你的要求、习惯等等
- 编辑组件状态不容易被获取到,并没有获取dom的click等原生HTML事件来的容易
- 第三方canvas引擎的学习成本,当然这有助于学习canvas技术
- canvas对于富文本的支持有限
- 使用dom我可以随心所欲
脑子里有一个声音异常强烈:TMD改成DOM+Position吧,学习canvas引擎咱专门去学一下好不好
因为对于PPT这样的"文档型"应用来说,DOM在功能完备性和开发效率上的优势,往往远大于Canvas在极限性能上的优势。
优势一:原生的富文本能力
这是DOM方案的"杀手锏"。一个设置了 contenteditable="true" 的 <div>,或者一个集成了 Tiptap / Quill 这样富文本编辑器的组件,免费提供了Canvas梦寐以求的一切:
- 文本选择和光标
- 复制、粘贴、撤销、重做
- 混合样式(粗体、斜体、颜色)
- 段落、列表、行高
对于PPT应用来说,仅此一项,DOM方案就几乎胜出了
优势二:项目复杂程度低
- 状态与视图绑定: 每一个PPT元素(文本框、图片)就是一个
DOM元素。 - 天然适配现代框架: 这与React、Vue等框架的工作方式完美契合。你的状态就是
[...objects],你的视图就是objects.map(obj => <div style={...}>...</div>) - "移动"就是"移动": 当用户拖动时,只需更新状态,框架会自动且高效地只更新那个
<div>的style属性 - 事件处理:
onClick?直接绑定在<div>上即可
优势三:更好的可访问性与调试
- 屏幕阅读器可以轻松阅读
<div>里的文本。 Ctrl+F查找、右键菜单、浏览器扩展都能正常工作。
DOM方案真的会慢吗?
DOM方案唯一的"缺点"是潜在的性能问题:当一个页面上有成千上万个DOM节点时,浏览器会变慢。
但对于PPT应用,这个"缺点"几乎不成立
- 对象数量可控: 一个PPT单页上有多少元素?几十个?顶多一两百个?这个数量级的DOM节点,对于现代浏览器来说毫无压力
只有构建的是像Figma那样(一个文档可能包含10万个图层)或在线游戏那样的应用时,Canvas的极限性能才变得有意义