停止使用 localStorage !

medium 优秀文章翻译,也增加自己的一些使用体验。

非标题党!本文标题很明确的想表达对 localStorage 的不推荐。

localStorage 的弊病

2009年 localStorage 诞生,简单来说就是 5MB 的字符串格式的存储。让我拆解下定义中的关键点。

  • 字符串集合:它只能存储字符串。如果你想要存储或者检索其他格式数据,你必须进行序列化和反序列化。假如你忘记了这一点,你将会遇到各种各样的网络Bug。例如当你存储 true 和 false 时,你还要注意处理 null、undefined、空字符串等潜在返回值。
  • 非结构化数据:JavaScript 结构化克隆算法用于复制复杂的 JavaScript 对象的算法。它通过递归输入对象来构建克隆,同时保持先前访问过的引用的映射,以避免无限遍历循环。postMessage , WebWorkers , IndexedDB , Caches API, BroadcastChannel, Channel Messaging API, MessagePortHistory API 都是采用的结构化数据! 采用该结构化数据就是为了解决序列化和反序列化 JSON 带来的问题。很遗憾的是 localStorage 并没有更新该特性,并且未来也没有推进的计划。
  • 安全妥协:你永远不会在任何持久化存储中保存敏感数据,但是开发者依旧会在 localStorage 中保存 Session IDs,JWTs、API keys 等敏感信息。这是个常见的安全隐患,你可以在 window.localStorage 中随意查阅。
  • 性能:localStorage 的性能相对于之前已经有了很好的优化,但是对于超量事务的并发应用程序来说,其性能瓶颈一样要重点考虑。
  • 大小限制:localStorage 有 5MB 的限制,而且可能被浏览器删除。对于现代应用来说,5MB 是很小的容量了,几乎很难存储任何媒体数据。它并不是一成不变的,在一些场景下,浏览器也会主动删除部分持久化存储中的数据,这是个通病,这也是何为常规日志上报会有数据丢失的原因之一。因此有甚至需要主动去管理这部分的数据的生命周期,尽管没人告诉你要做这个。还有个点就是存储剩余容量是无法查询的,因此你无法确定操作是否会以为容量达到上限而无法完整写入。
  • WebWorker 无法访问:localStorage 并不是面向未来的API,也不是适用于并放进程中。
  • 非原子化:localStorage 不保证并行操作中的原子性,也没有任何锁能够保证正在写入的数据不会被覆盖。
  • 无数据隔离:localStorage 仅仅是个字符串的对象,应用下所有数据都被混淆在一起,无法进行数据隔离。
  • 无事务:常规数据库都会支持事务操作,也没办法进行分组。所有操作都是同步的、非独立的、无锁定的。
  • 同步阻塞操作:localStorage 不是异步的,它会阻塞主进程。频繁的读取甚至会影响动画的流畅性,在移动端设备最为明显

WebSQL 何去何从?

WebSQL 目标是为 Web 提供一个简单的 SQL 数据库接口,但是浏览器支持程度确实不好。

你可能好奇它为啥会被抛弃?

  • 单一浏览器厂商实现:WebSQL 主要是 Chrome 和 Safari 实现的,由于 Mozilla 和 Microsoft 不支持,业内开发者几乎不采用它。
  • 非 W3C 标准:这个是至关重要的,W3C 在 2010 年将它从标准中移除了。
  • 与 IndexedDB 的竞争:IndexedDB 主要获得更多的关注,且被设计成标准的跨浏览器解决方案了。
  • 安全问题:一些开发人员和安全专家对WebSQL的安全性表示担忧。他们在很多方面都持怀疑态度,包括缺乏权限控制和SOL风格的漏洞。

最终 IndexedDB 成为浏览器存储的标准,被评价为强壮的、跨浏览器友好。但是大多数经验丰富的开发者都视其为瘟疫,那这种推荐又有什么意义呢?

Cookies 又如何呢?

cookie是1994年由网景公司的网络浏览器程序员卢·蒙图利(Lou Montulli)创建的。

本篇文章的标题实际应该是"停止使用 localStorage 和 Cookie",但是又不全对,我们应该使用安全的 cookies。

  • 4KB体积限制
  • 默认会被请求传输:非跨域 HTTP 请求会携带 cookie 数据,假如数据不需要被每个请求传输,就会带来带宽开销,导致网络加载速度变慢。
  • 安全隐患:cookie更容易受到XSS的攻击。由于cookie会自动包含在对域的每个请求中,因此它们可能成为恶意脚本的目标。
  • 过期:cookie被设计为在给定日期过期。

IndexedDB 呢?

  • 更好的性能:IndexedDB 操作是异步的,不和阻塞主进程。API 被设计为了事件驱动的。
  • 充足的存储配额:与localStorage的5MB上限相比,IndexedDB提供了更大的存储配额(取决于浏览器、操作系统和可用存储。
  • 可靠且结构化数据:Indexed 减少了强制类型转换,并且采用结构化克隆算法,保证数据的完整。

但是你大概并不想直接使用 IndexedDB。

IndexedDB 大概是避免过多依赖的例外。将 IndexedDB 视为后台数据库,你需要的是 ORM 或者 数据库处理程序来进行查询的管理。由于 IndexedDB 糟糕的 API 设计,你更想要一个 IndexedDB 库。

  • 基于 Promise
  • 更好使用
  • 减少样板代码
  • 关注于更关键的部分

本文比较推荐 dexie.js 和 idb 两个针对 indexedDB 的封装库,其中 idb 的体积是最小的,仅仅 1.19 KB,并不会给程序带来负担。

总结

本文的口号虽然是"停止使用 localStorage",但是在这个时代实际是难以实现的,但是我们确实应该朝着这个目标出发。

未来开发者应该从 Promise()、async/await 和结构化数据中或者更加清晰且有意义的知识,而不应该关注为何数字"0"在条件语句中会成为"true",而不应该愤怒与客户获得 null 的返回值。

由于 IndexedDB 的性能优势,你存储各种类型的数据,甚至可以使用游标来遍历所有对象。基于这种技术,你甚至可以构建客户端的搜索引擎,而不会像 localStorage 那样影响动画渲染。

IndexedDB is commonly described as "low-level" . There's absolutely nothing low-level about IndexedDB, it's just an API with an old-style and unfriendly syntax. But that doesn't negate it's underlying capabilities, hence common library usage.

你并不需要直接使用 API,一个体积很小的封装库可以帮助你规避这些。

相关推荐
Krorainas16 分钟前
HTML 页面禁止缩放功能
前端·javascript·html
whhhhhhhhhw37 分钟前
Vue3.6 无虚拟DOM模式
前端·javascript·vue.js
鱼樱前端39 分钟前
rust基础(一)
前端·rust
xw542 分钟前
Trae开发uni-app+Vue3+TS项目飘红踩坑
前端·trae
Dolphin_海豚1 小时前
vue-vapor 的 IR 是个啥
前端·vue.js·vapor
撰卢1 小时前
Filter快速入门 Java web
java·前端·hive·spring boot
ai小鬼头1 小时前
创业心态崩了?熊哥教你用缺德哲学活得更爽
前端·后端·算法
拾光拾趣录1 小时前
算法 | 下一个更大的排列
前端·算法
小屁孩大帅-杨一凡2 小时前
如何使用Python将HTML格式的文本转换为Markdown格式?
开发语言·前端·python·html
于慨2 小时前
uniapp云打包安卓
前端·uni-app