Skip to content
雲里
里雾

MMKV 与 JSI — RN 持久化的新架构路径

mindgym 开发 更新于 2026/4/12

react-native-mmkv 是微信团队 MMKV 库的 RN 移植版,基于 JSI(JavaScript Interface)实现同步读写,性能比基于 Bridge 的 AsyncStorage 快约 30 倍。它是 RN 新架构在生态库中最典型的 JSI 应用之一——理解 MMKV 的工作方式,就理解了 JSI 如何从根本上改变了 JS 与 Native 的通信模型。


概述:RN 持久化的问题

RN 应用需要持久化用户偏好、业务数据、缓存等小体量高频读写数据。AsyncStorage 是最早的方案,但它有三个固有限制:

  1. 强制异步。底层走 Bridge,每次读写要跨 JS 和 Native 两趟 JSON 序列化/反序列化。
  2. 全量序列化。改一个字段也要重新序列化整个 value。
  3. 性能天花板低。1000 次连续读取约 15000ms(MMKV 约 50ms)。

这些问题是 Bridge 架构的固有缺陷——不换通信模型就修不好。MMKV + JSI 从底层替换了通信方式。

RN 持久化迭代史


工作方式

底层存储:mmap + protobuf

mmap(内存映射文件)

传统文件 I/O 需要两次内存拷贝(磁盘 → 内核缓冲区 → 用户缓冲区)和两次上下文切换。mmap 把文件直接映射到进程的虚拟地址空间——读写文件变成读写内存地址,操作系统在背后异步刷脏页回磁盘。

MMKV 名字里的 “MM” 就是 Memory Mapped。

protobuf 编码

MMKV 不用 JSON,用类似 Protocol Buffers 的紧凑二进制编码。关键优势不在于压缩率,而在于追加写入:新数据直接追加到文件末尾,不需要重新编码整个文件。JSON 改一个字段就要重新生成整个字符串。

写入流程

MMKV.set('key', value)
  → protobuf 编码
    → 追加到 mmap 映射的内存区域
      → 同步返回
        → 操作系统后台刷脏页到磁盘

没有系统调用(mmap 之后读写是普通内存操作),没有 JSON 序列化,没有异步回调。

通信层:JSI 替代 Bridge

MMKV 本身是 C++ 库。在旧架构下,JS 调用 C++ 必须经过 Bridge:

AsyncStorage 流程:
  JS → JSON.stringify → Bridge 队列(异步) → Native JSON.parse
    → SQLite → JSON.stringify → Bridge 队列(异步) → JS JSON.parse → resolve(Promise)

MMKV + JSI 流程:
  JS → JSI 直调 C++ → 读 mmap 内存 → 同步返回

JSI(JavaScript Interface)让 JS 通过 Host Object 直接持有 C++ 对象引用,调用时同步执行 C++ 代码,无 JSON 序列化、无队列等待。不是 Bridge 的优化版,而是完全不同的通信模型。

性能差距来源(约 30 倍)

  1. Bridge 往返延迟:两次异步消息传递 + 队列等待(最大瓶颈)
  2. JSON 双向序列化:每次通信 stringify + parse
  3. 底层存储差异:SQLite 查询 vs mmap 内存读取
  4. Promise 调度:async/await 微任务开销

Zustand persist 集成

react-native-mmkv 的 API(getString/set/delete)和 Zustand persist middleware 要求的 StateStorage 接口(getItem/setItem/removeItem)几乎一对一映射,只需要一个薄 adapter:

export const mmkvStorage: StateStorage = {
  getItem(name) { return storage.getString(name) ?? null },
  setItem(name, value) { storage.set(name, value) },
  removeItem(name) { storage.delete(name) },
}

三个方法都是同步的(MMKV + JSI 的核心优势),但 Zustand persist 的接口允许返回 Promise,所以同步返回也完全兼容。

缺点

方案对比

维度AsyncStorageMMKVSQLiteWatermelonDB
通信机制Bridge(异步)JSI(同步)视库而定视版本而定
数据模型string → stringkey → string/number/boolSQL 表Observable 对象
适用场景旧项目兼容偏好/状态持久化结构化查询大量记录 + 实时 UI
Bundle size~50 KB~500 KB~1.5 MB~2 MB
加密支持内置 AES-128需 SQLCipher依赖底层

面试视角

为什么 MMKV 比 AsyncStorage 快?

三层:通信层(JSI 同步调用 vs Bridge 异步队列 + JSON 序列化)、存储层(mmap 内存读写 vs SQLite 查询)、接口层(同步返回 vs Promise 调度)。约 30 倍差距。

JSI 和 Bridge 的根本区别?

Bridge 是两个独立世界用 JSON 消息异步通信;JSI 是同一个进程里 JS 通过 Host Object 直接调用 C++ 函数——同步、无序列化、直接内存访问。

MMKV 数据量大了怎么办?

MMKV 适合 KV 场景(几百 KB 到低 MB)。数据增长到几万条记录时,应该引入 SQLite 做结构化查询,或在 MMKV 里按维度做 key 分片。


版本说明

本页基于 MindGym M1 阶段(Expo SDK 54, react-native-mmkv 3.x, 2026-04-13)。

参见

参考