# 对比

> 这个 Fabric.js 撤销重做库和 fabric-history、fabricjs-react、手写 toJSON 保存相比有什么不同，帮你选对方案。

Source: https://fabricjs-document-engine.jscrate.dev/zh/docs/overview/comparison
Last updated: 2026-09-28

大家通常先找一个 Fabric.js 撤销重做库，然后才发现还需要保存、id 和冲突检查。这篇文章对比几种常见方案。版本号于 2026 年 9 月在 npm 上核对。

## 一览

|                    | 手写 `toJSON`    | `fabric-history` 2.0    | `fabricjs-react` 2.2 | 这个包         |
| ------------------ | ---------------- | ----------------------- | -------------------- | -------------- |
| Fabric.js 版本     | 任意             | 5                       | 5 和 6               | 6 和 7         |
| 撤销和重做         | 自己写           | 有                      | 没有                 | 有             |
| 撤销怎么存         | —                | 每一步存整个画布的 JSON | —                    | 只存变化的对象 |
| 稳定的对象 id      | 没有             | 没有                    | 没有                 | 有             |
| 用存储保存和加载   | 自己写           | 没有                    | 没有                 | 有             |
| 自动保存和冲突检查 | 没有             | 没有                    | 没有                 | 有             |
| 保留自定义属性     | 每次调用都要列出 | 在画布上列出            | —                    | 注册一次       |
| 崩溃恢复           | 没有             | 没有                    | 没有                 | 有             |
| React hooks        | —                | —                       | 有                   | 有，可选       |

## 手写 `toJSON` 和 `loadFromJSON`

Fabric.js 本身就能把画布转成 JSON 再转回来。做演示时这就够了。真正给用户用时，工作才开始：稳定的 id、加载失败的图片、互相抢的加载、乱序到达的保存，还有撤销。[为什么需要文档引擎](https://fabricjs-document-engine.jscrate.dev/zh/docs/overview/why-document-engine)一文逐条列出了这些问题。

## `fabric-history`

`fabric-history` 是一个小巧的 Fabric.js 撤销重做库。导入一次后，它通过修改 `Canvas.prototype`，给每个画布加上 `canvas.undo()` 和 `canvas.redo()`。每一步都把整个画布存成 JSON 字符串，做法简单，但图一大就会变慢、占内存。2.0 版依赖 Fabric.js 5，也不负责保存、加载或分配 id。

如果你只要在一个小的 Fabric.js 5 画布上撤销，可以选它。

## `fabricjs-react`

`fabricjs-react` 给 React 提供了一个画布组件和一个用来拿到 Fabric.js 编辑器的 hook。它帮你在 React 里挂载画布，但不保存文档，也不记录历史，所以可以和这个包一起用。

## 这个包

当用户会在你的编辑器里保存作品时，就选这个包。撤销只存变化的部分，对象有几千个时每一步也很快。保存同一时间只跑一次，并带修订号检查，崩溃后未保存的内容也不会丢。它需要 Fabric.js 6 或 7。

如果你只要撤销、从不保存，一个更小的 Fabric.js 撤销重做库可能就够了。如果要保存，可以对照[上线清单](https://fabricjs-document-engine.jscrate.dev/zh/docs/production/production-checklist)，看看自己要写多少东西。

## 下一步

- [撤销和重做](https://fabricjs-document-engine.jscrate.dev/zh/docs/guides/undo-redo)：这里的历史记录是怎么工作的。
- [迁移](https://fabricjs-document-engine.jscrate.dev/zh/docs/guides/migration)：从 Fabric.js 5 的 JSON 迁移过来。
