localStorage存对象需先JSON.stringify再LZString.compressToUTF16压缩,读取时逆序解压解析;必须try-catch处理QuotaExceededError和null解压异常,并配合分片、结构化存储提升效率。

直接用 localStorage 存对象或长文本,很容易触达 5MB 上限,尤其在任务类、笔记类或低代码应用中。真正有效的扩容方式不是“换存储”,而是“压数据”——用压缩算法把内容变小,再存进去。关键不在压缩本身,而在压缩前后数据形态的正确处理。
先序列化,再压缩,顺序不能错
localStorage 只认字符串,任何对象、数组都必须先转成 JSON 字符串,才能交给压缩函数。反过来看,解压后得到的仍是字符串,必须再用 JSON.parse() 恢复结构。
- ❌ 错误:
LZString.compress({ name: '张三', age: 28 })—— 压缩函数不识别 JS 对象 - ✅ 正确:
const compressed = LZString.compressToUTF16(JSON.stringify(userData)) - 读取时也严格逆序:
JSON.parse(LZString.decompressFromUTF16(raw))
选对压缩方法,兼顾兼容与体积
LZ-String 提供多种输出格式,compressToUTF16 和 decompressFromUTF16 是推荐组合:生成的字符串仍是合法 JS 字符串,可直接存入 localStorage,无需 Base64 或额外转义;相比 compressToBase64,它在多数场景下压缩率更优,且浏览器解析更快。
PigX UI Pro 前端开发指南 - Vue 3 + TypeScript + Element Plus。当用户提到 PigX UI、PigX 前端、lgb-mgui 项目、Vue 3 企业级后台开发、Element Plus 后台开发时使用此技能。
- 避免用
compress/decompress(原始二进制格式),它返回非字符串类型,localStorage.setItem会静默转成[object Object] - UTF16 版本天然支持中文、emoji 等宽字符,无乱码风险
必须加 try-catch,否则失败无声无息
压缩过程本身几乎不会报错,但两个环节极易出问题:一是 localStorage.setItem 超限时抛 QuotaExceededError;二是解压时输入损坏或为空,LZString.decompressFromUTF16 直接返回 null,后续 JSON.parse(null) 报错。
- 写入时包裹:
try { localStorage.setItem('key', compressed); } catch (e) { console.warn('存储失败:', e.message); } - 读取时判空:
const raw = localStorage.getItem('key'); const json = raw ? LZString.decompressFromUTF16(raw) : null; return json ? JSON.parse(json) : null;
配合结构化设计,效果翻倍
光压缩不够,还得让数据本身更“瘦”。像 Nullboard 那样拆分存储:配置存 nullboard.conf,看板元数据存 nullboard.meta.{id},内容单独存 nullboard.data.{id}。每块数据独立压缩,既降低单次操作压力,又避免一处变更导致整块重写。
- 历史记录、撤销栈这类高频写入数据,压缩后分片存储(如每 800KB 一分)更稳妥
- 不常更新的静态配置,压缩一次即可,无需每次读写都重复压缩解压
- 结合
Locally这类库,还能自动加 TTL 和类型标记,进一步减少冗余

















