你知道 localStorage 但你知道 IndexedDB 吗?
2023年12月31日
现代浏览器中有几个让你可以储存资料的地方,假如打开浏览器的开发者工具,可以看到 LocalStorage、SessionStorage、CacheStorage、IndexedDB、Cookies 等。多数前端开发者平常可能比较常用 localStorage,但其实 IndexedDB 也很好用,在这篇文章让我们来聊聊 IndexedDB。
其实在全端双周报 #7 我们就提过 IndexedDB,在那期我们谈到专案管理软体 Linear 透过 IndexedDB 把资料快取在客户端,当使用者有重新整理页面时,先查看客户端快取的资料是否是最新的,如果是的话就不跟伺服器端拿资料,这大幅降低伺服器端的负担。
你可能会问,localStorage 也可以存东西、当作快取来用,那为何还需要 IndexedDB? 两者差别在哪? 首先,localStorage 是键值对 (key-value pair) 的储存形式,能够存的格式只有字串 (string),所以在存的时候,多半会搭配 JSON.stringify 来用。
而 IndexedDB 则是交易式资料库 (transactional database),并透索引 (index) 作为键来存取资料,而存的资料格式也不限于字串,基本上 JavaScript 的结构化克隆演算法能处理的物件,都能存在 IndexedDB。此外,IndexedDB 通常会用来处理比较大量的资料。
跟 localStorage 的另一个差别是,IndexedDB 目前在执行面都是非同步 (asynchronous),换句话说在存取资料时,不会阻塞应用程式的运作。而因为是交易式资料库,即使是非同步,IndexedDB 也能确保资料的完整性,在写入资料要不就全部成功,要不就整个全部失败,不会有部分存成功、部分失败的状况。
看完上面的比较,大概可以归结出,IndexedDB 是个非同步、可以拿来存比较大量资料的浏览器储存空间。那具体他可以拿来做什么呢? 如先前提到 Linear 用 IndexedDB 做快取,用 IndexedDB 的一个好处是,在离线的时候 (或是使用者的网路断掉),仍可以从 IndexedDB 拿资料,在技术上,我们会称这个为 persistent storing,举例来说,TanStack Query 有提供 persistQueryClient 可以搭配浏览器的储存机制,来做离线时的快取,提供更好的离线使用体验。
如果大家想试试看 IndexedDB,可以参考 Google web.dev 的这一篇使用说明 连结。不过实务上使用起来还是比较麻烦一点,因此更推荐直接用开源专案 localForage 连结,这个开源专案额外做一层封装,把原本比较麻烦使用的 IndexedDB 或 WebSQL,变得可以像 localStorage 一样简单操作。