「非同期設計レビュー」って何をする時間か
非同期処理のコードは、とりあえず動かすだけなら意外と簡単です。async/await を付けて、fetch を呼んで、console.log して終わり。
でも「速さ」「安定性」「UI の気持ちよさ」まで含めてちゃんと設計しようとすると、
一度立ち止まってコード全体を見直す時間が必要になります。
それが「非同期設計レビュー」です。
ここでは、
「どこをどう見ればいいか」を、チェックポイントと具体例で整理していきます。
実務のコードレビューで僕が必ず見る観点を、そのまま初心者向けにかみ砕きます。
依存関係の整理:「本当に順番にやる必要があるか?」
依存している処理と、していない処理を分けて考える
まず一番大事なのは、
「この非同期処理たちは、お互いに結果を必要としているか?」
という視点です。
例えば、次のようなコードがあったとします。
async function loadPage() {
const user = await fetchUser(); // 1
const posts = await fetchPosts(user.id); // 2
const notifications = await fetchNotifications(user.id); // 3
return { user, posts, notifications };
}
JavaScriptここでは、
2 と 3 は user.id に依存していますが、
2 と 3 同士は依存していません。
つまり、
「1 は先にやる必要があるけど、2 と 3 は同時にやっていい」
という構造になっています。
これをレビューで見つけたら、
次のように書き換えを検討します。
async function loadPage() {
const user = await fetchUser();
const postsPromise = fetchPosts(user.id);
const notificationsPromise = fetchNotifications(user.id);
const [posts, notifications] = await Promise.all([
postsPromise,
notificationsPromise,
]);
return { user, posts, notifications };
}
JavaScriptここでのポイントは、
「依存関係があるところだけ順番を守り、それ以外は並列にする」
という設計にできているかどうかです。
レビューでは必ず、
「この await は“依存のため”に必要なのか、“なんとなく”置いてあるのか」
を問い直します。
await の位置と数:「本当にそこまで待つ必要があるか?」
「結果をすぐ使う await」と「ただの中継 await」を見分ける
次に見るのは、await の置き方です。
例えば、こんなコード。
async function getUser() {
const user = await fetchUser();
return user;
}
JavaScriptこれは、こう書いても意味が同じです。
function getUser() {
return fetchUser();
}
JavaScript「中で何も加工せず、そのまま返しているだけ」の await は、
基本的に不要です。
レビューでは、
「この関数は本当に async である必要があるか?」
「return await になっていないか?」
を必ず確認します。
もう一つ、よくあるパターンを見てみます。
async function loadData() {
const a = await fetchA();
const b = await fetchB();
const c = await fetchC();
return { a, b, c };
}
JavaScriptこれも、依存関係がないならこう書けます。
async function loadData() {
const aPromise = fetchA();
const bPromise = fetchB();
const cPromise = fetchC();
const [a, b, c] = await Promise.all([aPromise, bPromise, cPromise]);
return { a, b, c };
}
JavaScriptレビューでは、
「順番に await しているけど、本当に順番が必要か?」
「まとめて await できないか?」
を必ずチェックします。
ここが重要です。
await は「書けば安全」ではなく、「意味を持って置くスイッチ」です。
設計レビューでは、その一つ一つに意味があるかを確認します。
キャッシュとバッチ:「同じことを何度もしていないか?」
同じリクエストを何度も飛ばしていないか
非同期設計レビューでよく見るのが、
「同じ API を、画面のあちこちから何度も呼んでいる」パターンです。
例えば、ヘッダーとサイドバーとメインコンテンツで、
それぞれが fetchUser() を呼んでいるようなコード。
async function renderHeader() {
const user = await fetchUser();
}
async function renderSidebar() {
const user = await fetchUser();
}
JavaScriptこういうのを見つけたら、
「Promise キャッシュ」や「グローバルな getUser()」への抽象化を提案します。
let userPromise = null;
function getUser() {
if (!userPromise) {
userPromise = fetchUser();
}
return userPromise;
}
JavaScriptレビューの観点としては、
「同じデータを、同じセッション中に何度も取りに行っていないか?」
「キャッシュできる単位はないか?」
を必ず見ます。
バッチ処理でまとめられないか
ID ごとに API を叩いているコードも要注意です。
async function loadUsers(ids) {
const users = [];
for (const id of ids) {
users.push(await fetchUser(id));
}
return users;
}
JavaScriptこれを見たら、
「サーバー側にバッチ API を用意できないか?」
「クライアント側でバッチングできないか?」
という話をします。
非同期設計レビューでは、
「回数を減らす」「まとめる」という視点がとても重要です。
速さだけでなく、サーバー負荷やネットワーク効率にも効いてきます。
UI と非同期の関係:「ユーザー体験を壊していないか?」
長時間処理で UI をブロックしていないか
レビューで必ず見るのが、
「重い同期処理が紛れ込んでいないか」です。
例えば、async 関数の中に巨大な for ループがある場合。
async function processData(arr) {
let sum = 0;
for (const item of arr) {
for (let i = 0; i < 100000; i++) {
sum += item * i;
}
}
return sum;
}
JavaScriptasync と書いてあっても、
中身が同期なら普通に UI をブロックします。
ここでは、
「チャンクに分割して、間に休憩を挟せないか?」
「本当にメインスレッドでやるべき処理か?」
を問い直します。
ローディングとフィードバックが設計されているか
非同期処理は「待ち」が必ず発生します。
レビューでは、
「その待ち時間にユーザーは何を見ているか?」
も必ず確認します。
ローディング表示があるか
先に出せる情報だけでも表示しているか
楽観的 UI にできる部分はないか
コードだけでなく、
「この await の間、画面はどうなっている?」
という会話をするのが、非同期設計レビューの大事な部分です。
エラーとタイムアウト:「失敗したときの顔つきはどうなっているか?」
エラーがちゃんと伝播しているか
非同期処理は失敗します。
ネットワークエラー、タイムアウト、サーバーエラー…。
レビューでは、
「この await が失敗したらどうなる?」
を一つずつ追いかけます。
try/catch が必要なところにあるか
Promise を返すだけの関数で、エラーが握りつぶされていないかPromise.all でどれか一つ失敗したときの挙動を理解しているか
特に、return await を使っている場合、
エラーのスタックトレースの見え方が変わることもあるので、
「本当にそれが必要か?」を確認します。
タイムアウトやリトライの設計があるか
長いレイテンシを前提にするなら、
「どこまで待つか」「失敗したらどうするか」も設計の一部です。
レビューでは、
「この API は永遠に待ち続ける設計になっていないか?」
「ユーザー操作に対して、許容できる待ち時間はどれくらいか?」
といった話もします。
非同期設計レビューは、
「成功パターンだけを見る時間」ではありません。
失敗や遅延も含めて、全体の振る舞いを確認する時間です。
計測と検証:「速そう」ではなく「速い」と言えるか?
実際に測るコードがどこかにあるか
最後に、
「この非同期設計は、本当に速くなっているのか?」
を確認するための計測があるかどうかを見ます。
console.time / console.timeEndperformance.now() を使った簡易計測
計測用のラッパー関数
どんな形でもいいので、
「測ろうと思えばすぐ測れる状態」になっているかを確認します。
設計レビューでよくやるのは、
「この書き方と、もう一つの案で、実際に何回か測ってみよう」
という提案です。
感覚ではなく数字で話せるようになると、
非同期設計の議論の質が一気に上がります。
初心者として「非同期設計レビュー」で本当に持っていてほしい視点
最後に、あなたの頭の中に置いておいてほしい質問をまとめます。
この await は、何に依存しているから必要なのか?
この処理は、本当は並列にできないか?
同じことを何度もやっていないか?キャッシュやバッチにできないか?
この処理の間、ユーザーは何を見ている?UI は気持ちいいか?
失敗したらどうなる?どこまで待つ?
「速そう」じゃなくて「速い」と言えるだけの計測をしたか?
自分の書いた非同期コードを一つ選んで、
この質問たちを一つずつぶつけてみてください。
それを繰り返していくと、
あなたの中に「非同期設計レビュー脳」が育っていきます。
その脳が育ったとき、
あなたはもう「async/await を知っている人」ではなく、
本当に意味での
「非同期処理を設計できるエンジニア」になっています。

