Open4
WebKitBlobResourceエラー1
SafariのindexedDBにBlob入れると、「エラー1」が出ることがある
「エラー1」だけでは原因を特定しにくいが、私の事例では以下の条件でエラーが発生した
- indexedDBからBlobを読み込む
- URL.createObjectURLで、BlobからobjectURLを生成する
- indexedDBに再度同じBlobを書き込むと「エラー1」になる
対処方法 BlobをcloneしてからindexedDBへ書き込む
FileReaderでデータ実体を読み直してcloneする
// WebKitBlobResourceエラー1対策
const clonedBlob = await new Promise<Blob>((resolve, reject) => {
const fileReader = new FileReader();
fileReader.onload = () => {
if (!(fileReader.result instanceof ArrayBuffer)) {
reject(new Error("Failed to read blob"));
return;
}
resolve(new Blob([fileReader.result], { type: blob.type }));
};
fileReader.onerror = () => {
reject(fileReader.error);
};
fileReader.readAsArrayBuffer(blob);
});
個人開発アプリがSafariでもまともに動くようになった
パフォーマンスに影響ありそうな方法だが、
indexedDBの読み込みより書き込みのほうが頻度が低いため、問題は起きなさそう
パフォーマンスの問題が生じた方法
indexedDBに直接Blob入れず、MIME typeとArrayBufferに分解してDBに入れる
DB読み込みが大幅に遅くなってしまった
画像を500枚くらいindexedDBに入れると、Android端末で全部読み込むまでに1分くらいかかってしまった
indexedDBのデータ構造を変えてマイグレーションする必要もあり、大掛かりになりやすい
うまくいかなかった方法
blob.slice()
やstructuredClone(blob)
でBlobをcloneする
const albumPutRequest = almapDB
.transaction(["album"], "readwrite")
.objectStore("album")
.put({
...photo,
blob: blob.slice(),
});
結局「エラー1」が出るままだった
データ実体はcloneされず、あくまでBlob Objectがcloneされるらしい