Blog
Blog copied to clipboard
本地存储方案介绍 —— 现有方案
本地存储方案介绍 —— 现有方案
文章将从 LocalStorage 开始讲起,聊到 localForage,在后续的篇章中将会说一说新的存储方案。
本地存储功能在我们站点应用中十分常见,LocalStorage,SessionStorage 等都是大家经常使用的。然后目前也有很多应用选择避免使用 LS、SS,而改用基于本地数据库(indexedDB, WebSQL 之类)的解决方案,这是为什么呢?
为什么好好的,大家都不使用 LocalStorage/SessionStorage 了?
LS 的弊端
LS 一推出就以其简单的 API 大受欢迎。基于 storage 规范(嗯,这个不是 HTML5 的内容),LS 拥有十分简单的 API:
localStorage.setItem( 'key', 'value' )
localStorage.getItem( 'key' ) // ===> 'value'
不得不说 LS 给开发者带来的很多好处:
- 特别特别的简单;
- 字符串存储,复杂数据可以用 JSON 字符串;
- 浏览器兼容性好;
随着 LS 被广泛地使用,它的弊端也慢慢为人所熟知:
糟糕的性能问题
LS 本质上是一种同步的行为,这意味着它在执行时会阻塞渲染,影响你的应用的体验。
每次 LS 执行文件 IO 都意味着对本地硬盘的操作,这可能会需要很多的时间,具体取决于系统执行的操作。而且,为了显得流畅,应用在加载时会等待 LS 内容加载至内存中,这意味着 LS 使用的越多,应用加载就越慢。
SSL 隔离
LS 遵循规范中基于 Scheme、hostname、unique port 的三者隔离特性。但是由于 LS 是明文存储,在安全页面和非安全页面中都不应该将敏感数据存储于 LS,所以 HTTP 和 HTTPS 的站点本应该可以同享 LS 内容,但是实际上却并非如此。
隐私模式数据丢失
LS 在隐私模式下会使用一个新的临时数据库,这意味着在隐私模式被关闭后,LS 的数据也将丢失。
存储限制
LS 的存储限制一般仅 5Mb 左右,并没有太好的解决方案进行 LS 的扩容。
值转义
LS 存储值的过程中会自行将非字符串类型值转义成字符串,是一个容易被人忽略的问题,比如:
localStorage.setItem( 'key', 900 )
localStorage.getItem( 'key' ) === 900 // false, return '900'
localStorage.setItem( 'key', {toString: function () {return '100'}} )
localStorage.getItem( 'key' ) === '100' // true
总之,大家都开始寻找更好的存储方案进行替代原来的 LS。
localForage
localForage 是一个快速的简单的 JS 存储工具。他使用的是异步存储(基于 IndexedDB 或者 WebSQL),并且它有一套类似 LS 的 API。
localForage 的优势
API 简单
localforage.setItem('key', 'value', function (err) {
// if err is non-null, we got an error
localforage.getItem('key', function (err, value) {
// if err is non-null, we got an error. otherwise, value is the value
});
});
Callback 和 Promise
由于 localForage 使用的是异步存储,所以提供的 API 是异步 API,localForage 同时提供了 Callback(Node-style,即回调第一个参数为 error) 和 Promise 的方式进行异步处理。
localforage.setItem('key', 'value', function (err) {
// if err is non-null, we got an error
localforage.getItem('key', function (err, value) {
// if err is non-null, we got an error. otherwise, value is the value
});
});
////
localforage.setItem('key', 'value').then(function () {
return localforage.getItem('key');
}).then(function (value) {
// we got our value
}).catch(function (err) {
// we got an error
});
存储值类型丰富
localForage 可以存储包括 Blobs、TypedArrays 和其他 JS 对象:
- Array
- ArrayBuffer
- Blob
- Float32Array
- Float64Array
- Int8Array
- Int16Array
- Int32Array
- Number
- Object
- Uint8Array
- Uint8ClampedArray
- Uint16Array
- Uint32Array
- String
多实例并存
LS 无法同时存储同 key 的多个值,localForage 可以通过实例化加以解决。
var store = localforage.createInstance({
name: "nameHere"
});
var otherStore = localforage.createInstance({
name: "otherName"
});
// Setting the key on one of these doesn't affect the other.
store.setItem("key", "value");
otherStore.setItem("key", "value2");
另外,由于 localforage 是基于 indexedDB 这类本地数据库的,所以没有存储限制,或者说在硬盘空间足够的情况下是不存在存储限制的。localforage 在数据存储的容量方面完胜 LS。