Madogiwa Blog

主に技術系の学習メモに使っていきます。

JavaScript: 大量の非同期リクエストを任意のサイズに分割して並列処理するメモ📝

フロントエンドでAPIリクエストを扱う際、大量のデータを一度に取得するとパフォーマンスに影響を与えることがあります。

単純な非同期リクエストを適切なサイズに分割し、Promise.allを使って効率的に処理するような実装をしたところパフォーマンス改善ができたのでメモ📝

サンプル

例えば、以下のように一度に大量のデータを取得する場合を考えます。

async function fetchData() {
  const ids = [1, 2, 3] // 大量のID
  const results = await getData({ "ids[]": ids });
  return results;
}

この方法では ids の数が多い場合、リクエストサイズが大きくなり、APIのレスポンス遅延やサーバー負荷の増加につながる可能性があります。

リクエストを分割してPromise.allで非同期処理を並列実行する

任意のサイズで配列を分割する

idsの配列を任意のサイズに分割するために配列を分割する split 関数を定義します。

export function split(array, chunkSize) {
  if (chunkSize <= 0) throw new Error("chunkSize must be greater than 0");
  const result = [];
  for (let i = 0; i < array.length; i += chunkSize) {
    result.push(array.slice(i, i + chunkSize));
  }
  return result;
}

この split 関数を用いることで、大量の ids を適切なサイズのチャンクに分割できます。

非同期処理を並列に処理する

データ取得時に ids を分割し、それぞれのチャンクをPromise.all で並列に処理するようにします。

const FETCH_CHUNK_SIZE = 20; // 1リクエストあたりの最大ID数

async function fetchDataInChunks() {
  const ids = [1, 2, 3] // 大量のID
  
  // IDリストを分割
  const idChunks = split(ids, FETCH_CHUNK_SIZE);
  
  // 並列リクエストを実行
  const results = (await Promise.all(idChunks.map(chunk => getData({ "ids[]": chunk })))).flat();
  
  return results;
}

おわりに

JavaScriptPromise.all、簡単に非同期処理を並列実行できて便利ですね〜!

参考

developer.mozilla.org