← すべての記事

MAX_WRITE_OPERATIONS_PER_MINUTEのエラー

Chrome の拡張機能を作っているとき、以下のエラーが出ます。 ``` Uncaught (in promise) Error: This request exceeds the MAX_WRITE_OPERATIONS_PER_MINUTE quota. ```

Chrome の拡張機能を作っているとき、以下のエラーが出ます。

Uncaught (in promise) Error: This request exceeds the MAX_WRITE_OPERATIONS_PER_MINUTE quota.

chrome.storage  |  API  |  Chrome for Developers

1分あたりに実行できる set、remove、clear オペレーションの最大数。これは 1 秒あたり 2 回で、短期間で 1 時間あたりの書き込み数よりも高いスループットを実現します。 この上限を超過する更新は直ちに失敗し、コールバックを使用している場合や Promise が拒否された場合は runtime.lastError を設定します。

この制限「MAX_WRITE_OPERATIONS_PER_MINUTE = 120」は、1分間に書き込み操作が120回まで(=1秒あたり約2回)ということになります。 要するに更新回数が120回までだよ、ということです。(大事なことなので2回)

例えば以下のようなことをしようとするとよく起こります。

  • 入力フォームの内容をリアルタイム保存しようとして、キー入力ごとに毎回書き込み
  • スライダーやチェックボックスの値が変わるたびに即座にストレージ更新
  • マウスの動きやスクロールなど頻繁に発生するイベントに対して即書き込み

特に入力フォームでのリアルタイム保存は、ユーザビリティ向上のために実装したくなる機能ですが、oninputイベントで毎回chrome.storage.local.set()を呼び出すと、長めのテキスト入力や編集作業であっという間に制限に達してしまいます。

この値の制限について調べたものを表にしてみました。

Chrome Storage の制限まとめ

ストレージ種類制限内容ソース
local全体の最大容量約 10 MB(Chrome 113 以前は 5 MB)developer.chrome.com
無制限化"unlimitedStorage" パーミッションで解除可能?Stack Overflow
sync全体の最大容量約 100 KBdeveloper.chrome.com
1アイテムの最大サイズ約 8 KBdeveloper.chrome.com
最大アイテム数512developer.chrome.com
書き込み回数制限1分あたり 120 回、1時間あたり 1,800 回developer.chrome.com

### 対処法

こういうケースでは大体3択の方法で解決することになります。

  1. debounce(デバウンス) 短時間の連続処理をまとめる手法です。最後の操作から指定した時間が経過した後に実行されます。
  2. throttle(スロットル) 一定周期の間隔で実行を制限する手法です。指定した間隔内では最初の実行のみを有効にします。
  3. キューイング 書き込み操作を順番待ちさせて、制限内で安全に処理する手法です。

ですが、UIなので基本的にはdebounceが採用されることが多いようです。

サンプルコードとしては以下になります。

function debounce(fn, delay) {
let timerId;
return function(...args) {
clearTimeout(timerId);
timerId = setTimeout(() => fn.apply(this, args), delay);
};
}
// 使い方例
const writeToStorage = (data) => {
chrome.storage.local.set(data);
};
// デバウンスを適用
const debouncedWrite = debounce(writeToStorage, 1000);
// 何度呼ばれても1秒以内は1回だけ実行される
debouncedWrite({ key: 'value1' });
debouncedWrite({ key: 'value2' });

これと同様の実装をすることで解決しました。


調べてみると

  1. chrome.storage に直接書かずwindow.localStorage や IndexedDB に一時保存
  2. 定期的に chrome.storage へ同期 といったように保存対象データの分離をすることもあるようです。次はこっちでやろうかな。