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; }
おわりに
JavaScriptのPromise.all、簡単に非同期処理を並列実行できて便利ですね〜!