共计 3307 个字符,预计需要花费 9 分钟才能阅读完成。
浏览器内置模块 kv-storage 异步版的 localStorage
LocalStorage 大家都不陌生基本上每天都在跟他打交道。但这是个会阻塞主线程的同步 API,很多情况下存取大量数据可能会造成性能问题。????
为了解决这个问题,我们可能会使用 IndexedDB,但后者难以操作,虽然目前有第三方模块可以很轻松操作 IndexedDB,但仍然不是最好的解决方案。
有没有一种既能够像 LocalStorage 一样简单的 API,又能够拥有 IndexedDB 这样的异步存取数据的能力的前端存储解决方案呢❓
这个时候 Chrome 开发团队目前正在测试一款名为 std:kv-storage 的 浏览器内置模块 ????
啥是内置模块?
内置模块 Built-in modules 跟 JS 模块一样,只不过他并不用从远端下载下来使用,而是与浏览器绑定在一起的。
当然,这种内置模块与传统的 web API 最大的不同之处就是需要使用 esm 语法进行导入 ⬇️,这种模块并不会暴露在全局作用域中,你没办法直接通过 window.xxx 来引用,而是需要先 import
在 chrome 中内置模块的标识符是 std:
kv-storage
kv-storage 模块在 API 上与 LocalStorage 类似。常用的方法有:
get() 读取数据
set() 写入数据
delete() 删除数据
clear() 清空数据
所有的上述方法都会返回一个 Promise 对象,也就是说这些都是异步的 ????
官网规范:https://wicg.github.io/kv-sto…
不说那么多,先来看看这个内置模块到底怎么用:
环境配置
首先我们需要一个 74 版本以上的 Chrome 浏览器,并且需要打开 chrome://flags/#enable-experimental-web-platform-features
浏览器需要支持 modules 在 Chrome 中,要求版本在 61 以上
编写演示代码
首先这里用一个 index.html 文件配合 vscode 的 Live Server 做演示
我们要做的一个简单的功能是创建一个表单,用户填写表单过程中,点击保存按钮,填写在表单内的数据都会存储在 kv-storage 中,即便用户不小心刷新了浏览器,点击恢复按钮即可恢复数据。
首先我们需要一个表单:
<form action=””>
<input type=”text” name=”username” placeholder=”username”>
<input type=”text” name=”message” placeholder=”message”>
<button type=”submit”> 保存 </button>
<button type=”reset”> 恢复 </button>
</form>
然后定义一个 type 为 module 的 script 标签
<script type=”module”></script>
script 标签内就是我们的主要逻辑:
<script type=”module”>
import {storage} from ‘std:kv-storage’ // 首先导入内置模块 kv-storage
{
(async () => {
// 定义两个事件处理函数
document.querySelector(‘form’).addEventListener(‘submit’, handleClickSubmit)
document.querySelector(‘form’).addEventListener(‘reset’, handleClickRestore)
// 当点击保存
async function handleClickSubmit(e) {
e.preventDefault()
let inputs = document.querySelector(‘form’).querySelectorAll(‘input’)
let kvData = Array.from(inputs).map(item => ({ name: item.getAttribute(‘name’), value: item.value }))
await storage.set(‘formData’, kvData) // 获取表单数据并保存在在 key 为 formData 的 store 中
}
// 恢复数据事件处理函数
async function handleClickRestore(e) {
let formData = await storage.get(‘formData’) // 读取 formData 数据
document.querySelector(‘form’).querySelectorAll(‘input’)
formData.forEach(data => {
let {name, value} = data
document.querySelector(`input[name=${name}]`).value = value // 将数据注入 input 元素内
})
}
})()
}
</script>
以上,非常简单的一个 DEMO,我们来看看效果:
输入数据并点击保存:
我们去 indexdDB 中查看数据是否保存成功:
默认在 kv-storage:default 数据库的 store 集合中出现一条 formData 数据,值就是表单数据数组
然后我们刷新浏览器并点击恢复,kv-storage 从 indexedDB 中又读取了数据并注入到表单中
即便是关闭浏览器重新打开依然能够恢复数据
主要的使用方法大概就是这样,目前位置该内置模块仍然在测试中。
兼容
官方给了一套兼容性解决方案,针对检测是否存在该内置模块的 import map 方法;还有针对是否支持 modules 的 nomodules 方案。
检测是否存在内置模块
新增标签设置 type 为 importmap 创建 importmap,当使用 import 方法引入模块的时候,按照路径首先检查是否能够通过 import {storage} from ‘std:kv-storage’ 引入,如果不可以,则尝试使用 polyfill import {storage} from ‘/path/to/kv-storage-polyfill.mjs
<!– The import map is inlined into your page –>
<script type=”importmap”>
{
“imports”: {
“/path/to/kv-storage-polyfill.mjs”: [
“std:kv-storage”,
“/path/to/kv-storage-polyfill.mjs”
]
}
}
</script>
<!– Then any module scripts with import statements use the above map –>
<script type=”module”>
import {storage} from ‘/path/to/kv-storage-polyfill.mjs’;
// Use `storage` …
</script>
相关文档见:https://github.com/WICG/impor…
检测是否支持 modules
<!– 支持 ES Modules 的浏览器加载 main.mjs –>
<script type=”module” src=”main.mjs”></script>
<!– 旧浏览器不支持 ES Modules 会加载该文件,同时支持 ES Modules 会忽略这个文件 –>
<script nomodule src=”main.es5.js”></script>
这里附上 polyfill:https://github.com/GoogleChro…
Chrome 发布的 kv-storage 并不是说有多么的强大,毕竟现在 LocalForage(https://localforage.docschina… 也已经在业内很频繁在用了。作为第一个内置模块,虽现在不建议在生产模式中使用,但足以遇见在不久的将来这中内置模块的方式可能成为一种趋势。
参考:
https://github.com/WICG/kv-st…
https://github.com/GoogleChro…