14
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

ブラウザの新しいstorage moduleのKV Storageを試してみた!

Last updated at Posted at 2019-03-31

参考・関連リンク

注意

記事の内容に間違いなどありましたらご指摘お願いします:bow:

KV Storageとは

ブラウザベンダやWebパフォーマンスの専門家は、この10年間の大部分でlocalStorageは動作が遅く、Web開発者はそれを使うのをやめるべきだと言ってきました。

公平に言うと、これを言っている人々は間違っていません。 localStorageは、メインスレッドをブロックする同期APIです。アクセスするたびに、ページがインタラクティブに表示されなくなる可能性があります。

問題は、localStorage APIが非常に単純で、localStorageの唯一の非同期的な代替方法がIndexedDBであることです。これは(使いやすさや使いやすさのために知られていません)。

そのため、開発者は使いにくいものとパフォーマンスに悪いもののどちらかを選択できます。そして、実際には非同期ストレージAPIを実際に使用しながらlocalStorage APIのシンプルさを提供するライブラリもありますが、その中にはファイルサイズのコストがかかり、パフォーマンスの予算を浪費する可能性があります。

しかし、ファイルサイズのコストを支払う必要なしに、localStorage APIの単純さで非同期ストレージAPIのパフォーマンスを得ることが可能だったらどうでしょうか。

まあ、すぐにあるかもしれません。 Chromeは組み込みモジュールと呼ばれる新機能を試しています。最初に出荷する予定の機能は、KV Storageという非同期のキー/値ストレージモジュールです。

localStorageと違い非同期で、かつ簡単に扱える、KV Storage (Key-Value型データベース)の機能のようです。

動くサンプル

chromeのバージョン73だと動かすことができません。※2019/03/31現在

Note: The KV Storage module is currently available in Chrome 74 if you have the experimental web platform features flag turned on: (chrome://flags/#enable-experimental-web-platform-features).

image.png

参考ページにある通りに、実験用Webプラットフォーム機能フラグをonにすると動かすことができたので、この記事ではその状態で試していきます。

chrome://flags/#enable-experimental-web-platform-features

こちらを Enabled にしてchromeを再起動する

image.png

ほぼ参考ページのサンプル通りですが、このように簡単に動かすことができました

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <script type="module">
        import { storage } from "std:kv-storage";

        (async () => {
            const oldPreferences = await storage.get("preferences");

            document.querySelector("form").addEventListener("submit", async e => {
                e.preventDefault();
                const newPreferences = Object.assign({}, oldPreferences, {
                    date: new Date().toLocaleString()
                });

                await storage.set("preferences", newPreferences);
                console.log(await storage.get("preferences"));
            });
        })();
    </script>
</head>
<body>
    <form><input type="submit"></form>
</body>
</html>

image.png

ブラウザ対応

polyfillを使う

$ npm i kv-storage-polyfill

参考ページの通りだとこういう書き方になるようです

コードはこちらにも用意しました

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>

    <script type="importmap">
    {
        "imports": {
            "/node_modules/kv-storage-polyfill/dist/kv-storage-polyfill.mjs": [
                "std:kv-storage",
                "/node_modules/kv-storage-polyfill/dist/kv-storage-polyfill.mjs"
            ]
        }
    }
    </script>

    <script type="module">
        import { storage } from '/node_modules/kv-storage-polyfill/dist/kv-storage-polyfill.mjs';

        (async () => {
            const oldPreferences = await storage.get('preferences');

            document.querySelector('form').addEventListener('submit', async e => {
                e.preventDefault();
                const newPreferences = Object.assign({}, oldPreferences, {
                    date: new Date().toLocaleString()
                });

                await storage.set('preferences', newPreferences);
                console.log(await storage.get('preferences'));
            });
        })();
    </script>
</head>
<body>
    <form><input type="submit"></form>
</body>
</html>

参考:https://github.com/WICG/import-maps#for-built-in-modules-in-browsers-without-import-maps

参考に書いてあることのまんまですが、以下のように動作してくれるとのことです

  • importmapをサポートしていないブラウザはpolyfillを受け取ります
  • importmapをサポートしているがKV Storageをサポートしていないブラウザは、polifillのURLからそれ自体へのマッピングになるので、polifillを受け取ります
  • importmapとKV Storageの両方をサポートするブラウザは、polyfill URLからstd:kv-storageへのマッピングになるため、組み込みモジュールを受け取ります

polyfillを使うことで、Safariでも動作することが確認できました

image.png

API

※以下を参考にいくつか試してみました、詳細知りたい方は以下を参考にしてください:bow:

基本的な使い方

    <script type="module">
        import { storage } from "std:kv-storage";

        (async () => {
            console.log(await storage.get("category")) // undefind
            await storage.set("category", "hoge"); // 値をセット
            console.log(await storage.get("category")) // hoge
            await storage.delete("category"); // 値を削除
            console.log(await storage.get("category")) // undefind

            await storage.set("foo", 1);
            await storage.set("bar", 2);
            for await (const [key, value] of storage.entries()) {
                console.log(key, value); // 「foo 1」「bar 2」がそれぞれ出力
            }
            await storage.clear() // 全て削除
            console.log(await storage.get("foo")) // undefind
            console.log(await storage.get("bar")) // undefind
        })();
    </script>

image.png

new StorageArea()

new StorageArea とすることで、データをそこに保存することができます。
キー名が衝突する可能性が低くなります

    <script type="module">
        import { storage, StorageArea } from "std:kv-storage";

        (async () => {
            await storage.set("mycat", "Tom");
            console.assert(await storage.get("mycat") === "Tom");

            const otherStorage = new StorageArea("unique string");
            console.assert(await otherStorage.get("mycat") === undefined);
            await otherStorage.set("mycat", "Jerry");
            console.assert(await otherStorage.get("mycat") === "Jerry");
        })();
    </script>

最後まで読んでいただいてありがとうございましたm(_ _)m

14
6
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
14
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?