localStorage 你很好,我选 IndexedDB
在 Web 开发的早期,我们对 localStorage
是爱得深沉的。
简单的 API,直接调用就能存数据,写起来干净利落。
js
localStorage.setItem('theme', 'dark');
用过的人都懂,仿佛就是前端开发入门的"Hello World"。
但当应用体积变大,需求复杂了,我意识到,
是时候和 old friend 分手了。
我不是不爱你,只是你真的满足不了我了(渣言渣语~)。
大家好,我是芝士,欢迎点此扫码加我微信 Hunyi32 交流,最近创建了一个低代码/前端工程化交流群,欢迎加我微信 Hunyi32 进群一起交流学习,也可关注我的公众号[ 前端界 ] 持续更新优质技术文章
你很好,但问题也不少
1. 安全问题:XSS 一旦发生,localStorage 首当其冲
localStorage
是同步 API,不受同源页面任何 JS 限制,这也意味着:
js
// 如果页面存在 XSS 漏洞
const token = localStorage.getItem('authToken');
// 那你的用户登录态,可能就被黑了
对攻击者来说,这比写 cookie 更简单。
2. 性能问题:你会阻塞 UI 主线程
在现代前端应用中,我们尽量避免"卡顿"。
但只要用到 localStorage.setItem()
,尤其是数据一大,整个主线程就像被泼了冷水。
js
// 会阻塞页面渲染,影响用户体验
localStorage.setItem('hugeData', massiveJsonString);
这在写入缓存、异步数据同步中,非常危险。
3. 容量限制:你装不下我想存的世界
现代应用动不动就要缓存几百 MB 的图、音、视频资源。而 localStorage
的可用空间......顶天就 5MB。
更别说,它只支持字符串,所有数据都得自己 JSON.stringify()
/ parse()
,很麻烦。
js
// 不能直接存对象,也不能存二进制
localStorage.setItem('user', JSON.stringify(userObj));
IndexedDB:我的新选择
我承认,第一次接触 IndexedDB
,我是拒绝的。
API 繁琐、异步、回调多、还有版本控制 ------ 这谁顶得住?
直到我真正用上它,我才明白:这是为现代 Web 应用而生的本地数据库。
非阻塞,异步存储的典范
IndexedDB 所有操作都是异步的,写再多也不会卡住页面。
js
const dbRequest = indexedDB.open('MyApp', 1);
dbRequest.onsuccess = () => {
const db = dbRequest.result;
const store = db.transaction(['users'], 'readwrite').objectStore('users');
store.add({ id: 1, name: 'Alice' });
};
再也不用担心卡顿、闪屏、用户诧异地问:"刚刚页面是不是卡住了?"
结构化对象 + 二进制,一把拿捏
不用再手动序列化、反序列化。直接存对象,存 Blob,存 Buffer,存你想存的一切。
js
store.add({
id: 2,
name: 'Bob',
avatar: blobData, // 二进制数据
preferences: { theme: 'dark', language: 'en' }
});
这就是浏览器原生支持的 NoSQL 数据库体验。
存储空间,几乎无限
一般来说,IndexedDB
的存储上限在几百 MB 甚至数 GB。
如果你在做离线应用、缓存图片资源、预存图谱模型,这就是你最好的选择。
localStorage
只能存备忘录,而 IndexedDB
可以做整套图书馆管理。
localStorage 也有它的位置
别误会,我不是全盘否定 localStorage
。
像这类"小而简单"的场景,localStorage 依旧是你的好拍档:
- UI 状态缓存(主题、语言)
- 非敏感布尔标记(关闭广告提示框)
- 临时、简单的设置项
js
localStorage.setItem('theme', 'dark');
localStorage.setItem('hideModal', 'true');
但你只要一涉及到性能、容量、安全性,我建议你立刻切换 IndexedDB。
迁移指南:如何平滑过渡?
1. 先审查当前 localStorage 用法
js
const auditLocalStorage = () => {
const result = {};
for (let i = 0; i < localStorage.length; i++) {
const key = localStorage.key(i);
result[key] = localStorage.getItem(key)?.length || 0;
}
return result;
};
2. 设计数据库结构(类似建表)
js
const schema = {
name: 'MyAppDB',
version: 1,
stores: [
{
name: 'userStore',
keyPath: 'id',
indexes: [{ name: 'email', keyPath: 'email', unique: true }]
},
{
name: 'cacheStore',
keyPath: 'url',
}
]
};
如果你觉得 API 太原始,还可以用第三方封装库,如:
- localForage:封装了 IndexedDB / WebSQL / localStorage,统一 Promise API
- Dexie.js:提供类 SQL 查询方式,更适合开发者
总结:不是分手,是升级
localStorage
之于前端,就像 Nokia 之于手机历史 ------ 功不可没,但终究被替代。
当你的项目:
- 对性能有要求
- 要求安全可靠的数据存储
- 需要存储海量结构化数据
那么,是时候说一句:
localStorage,你很好,但我选 IndexedDB。
如果你想了解如何一步步在项目中引入 IndexedDB 或封装 localForage,欢迎留言交流,我可以写一篇实战教程来补上这块拼图 👀
大家好,我是芝士,欢迎点此扫码加我微信 Hunyi32 交流,最近创建了一个低代码/前端工程化交流群,欢迎加我微信 Hunyi32 进群一起交流学习,也可关注我的公众号[ 前端界 ] 持续更新优质技术文章
写在最后 :最好的本地存储方案,从不是最流行的,而是最适合你项目需求的那一个 。希望你不再被 5MB 局限,也别再手动 JSON.stringify()
了。
下一次存储用户数据时,不妨尝试一下 IndexedDB 吧,它可能会让你彻底"改观"。