はじめに
オーディオファイルなど、フロントエンドで何か静的なデータをロードして使うことはあると思います。
今個人で開発しているサービスでは、ページの遷移ごとにオーディオファイルをロードし再生しようとしていました。
しかし、サービスの特性上、3G回線で問題なく稼働することが求められ、単純なfetchを都度行なっているとページの動作が重たくなってしまうという問題がありました。
この問題を解決するため、ページを開く前にオーディオデータをロードし、それをローカルのストレージに保存させることでページの挙動を安定させました。
この記事では、行なった実装の内特に「fetchしたデータをbase64に変換してIndexedDBに保存する」部分についてまとめたいと思います。
IndexedDBとは
IndexedDBとは、ブラウザに多様なデータを保存するためのAPIです。
詳しくはドキュメントをご覧ください。
IndexedDBは生のインターフェースをそのまま触るのは複雑性もあり結構難易度が高いので、ライブラリを利用することが推奨されています。
ライブラリは以下のようなものがあります。
その他のライブラリについてはドキュメントをご覧ください。
実装
今回は簡単なKVSとしてIndexedDBを利用したいので、インターフェースがシンプルな
を利用して実装します。
実装したコードは以下の通りです。(オーディオデータを前提にしています)
import { set, get, clear } from "idb-keyval";
export const getAudioCache = async (url: string) => {
return await get<string>(url);
};
export const cacheAudio = async (url: string) => {
const response = await fetch(url);
const arrayBuffer = await response.arrayBuffer();
const base64 = Buffer.from(arrayBuffer).toString("base64");
const data = `data:audio/mp3;base64,${base64}`;
await set(url, data);
return data;
};
export const clearAudioCache = async () => {
await clear();
};
cacheAudio
を実行することで、urlで指定されたオーディオデータをbase64の音声データとしてIndexedDBに保存します。
保存したデータを取得したい場合はgetAudioCache
を用います。
また、IndexedDBは基本的に削除を行わない限り永続的に残り続けるので、削除をしたい場合はclearAudioCache
を実行してデータの削除を行います。