更好的不可变性
更快的不可变更新
高效的 JavaScript 不可变更新库。像修改普通数据一样修改草稿,即可得到下一个不可变状态。
完成相同更新的耗时
越短越好
- Mutative1 倍
- Immer3.6 倍
- Immer,自动冻结6.6 倍
简单
告别层层展开,轻松更新状态
将列表最后一项标为完成,再添加一项。展开语法需要逐层复制状态;使用 Mutative,只需修改草稿。
展开语法
const nextState = {
...state,
list: [
...state.list.slice(0, 2),
{
...state.list[2],
done: true,
},
{ text: 'Learn Mutative', done: true },
],
};使用 Mutative
import { create } from 'mutative';
const nextState = create(state, (draft) => {
draft.list[2].done = true;
draft.list.push({ text: 'Learn Mutative', done: true });
});高效
设计使然,快于 Immer
每次更新最多复制每个对象一次,并在副本上原生移动数组元素,无需逐个经过草稿代理。
3.6 倍
相同配置下相对于 Immer 的性能倍数
614 个测量案例中,Mutative 在 595 个案例里更快
6.6 倍
各自默认配置下相对于 Immer 的性能倍数
157 个测量案例中,Mutative 在 154 个案例里更快
97
基准工作负载
每项结果均与手写 reducer 核对
每次更新耗时,相对于 Mutative
越短越好
- Mutative
- Immer
- Immer,自动冻结
200 次 RTK Query 风格更新
100 个待处理请求和 100 个已完成请求
相对 Immer 加速 1.1 倍
更新小对象的一个字段
一个小型普通对象
相对 Immer 加速 1.4 倍
向 Set 添加一个数字
包含 10,000 个数字的 Set
相对 Immer 加速 31 倍
删除第一行
使用 shift() 的 10,000 行数组
相对 Immer 加速 1,052 倍
| 工作负载 | Mutative | Immer | Immer,自动冻结 | 相对于 Immer 的性能倍数 |
|---|---|---|---|---|
| 200 次 RTK Query 风格更新100 个待处理请求和 100 个已完成请求 | 1,001 µs | 1,133 µs | 4,795 µs | 1.1x |
| 更新小对象的一个字段一个小型普通对象 | 0.51 µs | 0.69 µs | 0.95 µs | 1.4x |
| 向 Set 添加一个数字包含 10,000 个数字的 Set | 29.5 µs | 904 µs | 975 µs | 31x |
| 删除第一行使用 shift() 的 10,000 行数组 | 7.04 µs | 7,408 µs | 8,137 µs | 1,052x |
卡片中的倍数为全部 97 项工作负载中,Immer 耗时与 Mutative 耗时之比的几何平均值。 查看基准测试
生产环境
从 Immer 到 Mutative
看看迁移到 Mutative 的开源项目如何评价(以下为引文译文)。
“使用 Mutative 替代 Immer 后,主线程脚本执行时间减少了约 1 秒。”
在客户端用 Mutative 替换了 Immer。
管理面板、内部工具与仪表盘
拉取请求,2025 年 2 月“Mutative 单次事务约耗时 3 ms。”
使用 Immer 时,单次事务约需 8 ms,增加待处理事务后约为 40 ms。
提供认证、权限、存储和在线状态的后端
拉取请求,2024 年 9 月“……你会感受到应用响应速度的小幅提升。”
在 3.0.11 版本用 Mutative 替换了 Immer。
端到端加密的笔记应用
发布说明,2024 年 7 月“所有插件 store 现已使用 zustand-mutative 进行不可变状态更新,它比 Immer 更快。”
在 42 版本将插件 store 迁移到 zustand-mutative。
React 富文本编辑器
版本发布,2025 年 1 月其他使用项目:Mol*、OpenRewrite 和 MSW Data。查看使用 Mutative 的项目
功能
不可变更新所需的功能
为多种数据结构提供草稿,按需开启补丁、冻结、标记与严格模式。
生态系统
融入你的技术栈
基于 Mutative,支持 React、Zustand、Jotai、XState、Yjs 等的生态库。