IndexedDB可高效存储离线地图瓦片,以z/x/y为键、Blob或ArrayBuffer为值;需正确处理二进制数据、设计键结构(如字符串键或复合索引)、配合缓存与容量管理策略。

IndexedDB 可以高效存储离线地图瓦片(通常是 PNG/JPEG 格式),核心思路是:把瓦片的唯一标识(如 z/x/y)作为 key,二进制数据(Blob 或 ArrayBuffer)作为 value 存入对象仓库。关键在于正确处理二进制数据、设计合理的键结构,并配合缓存策略使用。
创建支持二进制存储的数据库
IndexedDB 原生支持 Blob 和 ArrayBuffer,无需转 base64(避免体积膨胀和编码开销)。初始化时需声明版本并建立对象仓库,建议为瓦片设置复合主键或使用自定义 keyPath:
- 用字符串键(推荐):
`${z}/${x}/${y}`作为主键,直观且便于按层级查询 - 若需范围查询(如某一层级所有瓦片),可设
keyPath: ['z', 'x', 'y']并建多索引 - 对象仓库启用
autoIncrement: false,确保手动控制 key
存瓦片:从网络请求到 IndexedDB
获取瓦片后,直接存原始响应体(response.arrayBuffer() 或 response.blob()),避免中间转换:
你接手一个需求时,是不是经常这样:"改一个小字段 → 结果把不相关的代码也改了"、"需求说得很模糊 → 做着做着发现跑偏了"、"数据库加个字段 → 上线才发现漏了数据兼容"、"做了个新功能 → 一个月后自己都忘了当时怎么设计的"、"写到一半被中断 → 再回来不知道从哪继续";这个 Skill 就是专门解决这些问题的。 它会自动探测你的项目环境(JDK、Spring Boot、ORM、数据库、前端框架),记在
- 发起 fetch 请求,设置
cache: 'no-store'避免被 HTTP 缓存干扰离线逻辑 - 调用
response.arrayBuffer()得到二进制数据,传入put()方法 - 事务需指定
readwrite模式,错误时捕获并降级处理(如记录失败 tile)
读瓦片:优先查库,未命中再请求
地图渲染时先查 IndexedDB,命中则构造 URL.createObjectURL(blob) 供 <img> 使用;未命中再发起网络请求并同步存库:
立即学习“Java免费学习笔记(深入)”;
- 使用
get()查询z/x/y键,返回Promise<blob undefined></blob> - 查到后调用
URL.createObjectURL(blob),赋值给 img.src;注意后续需调用URL.revokeObjectURL()释放内存 - 可加一层内存 Map 缓存已解析的 blob URL,减少重复 create/revoke
管理与清理:避免无限增长
离线瓦片易占用大量空间,需主动控制容量:
- 按缩放级别(z)或地理范围(如 bbox)组织数据,删除过期/低频瓦片
- 利用 IndexedDB 的
delete()或游标遍历批量清理(例如删除 z < 5 的所有瓦片) - 监听
storage事件或定期检查navigator.storage.estimate(),接近限额时触发清理

















