こんにちは、なかにしです。
最近は本業も忙しいのですが、
引っ越しをしたのでさらに忙しくなっています。
引っ越し業者は高いですし、
気分転換も兼ねて家具を一新することにしたので、
最終的に段ボール10個くらいに収まりました。やったね。
今回は非同期処理についてです。
現在はReactでフロント部分を書いているのですが、
コードレビューする時にこれはもったいないと思った点があったので共有です。
いってみよう!
コード概要
ざっくりそのコードを再現します。
  const fetchData = async () => {
     // データを取得して返す処理
  };
  const fetchData2 = async () => {
    // データを取得して返す処理
  };
  const fetchData3 = async () => {
    // データを取得して返す処理
  };  
  const getUserData = async () => {
    // データ取得
    const responseData = await fetchData();
    const responseData2 = await fetchData2();
    const responseData3 = await fetchData3();
    // responseData, responseData2, responseData3を使用した処理
  };3カ所からデータを取得するようなコードです。
これの勿体ないところは、「3カ所が各々、非同期になっている所」です。
確かにデータ取得後、そのデータを使用した処理が続いているので、awaitで待つのは正しいのですが、1カ所ずつ実行結果を待つ必要はありません。3カ所の結果が返ってくるのを待てば良いのです。
つまり、「1カ所データ取得×3」ではなく、
「3カ所データ取得×1」にしましょうという話です。
以下が修正後のコードになります。
  const fetchData = async () => {
     // データを取得して返す処理
  };
  const fetchData2 = async () => {
    // データを取得して返す処理
  };
  const fetchData3 = async () => {
    // データを取得して返す処理
  };
  const getUserData = async () => {
    // データ取得
    const [responseData, responseData2, responseData3] = await Promise.all({fetchData(), fetchData2(), fetchData3() });
    // responseData, responseData2, responseData3を使用した処理
  };これで、3つのデータ取得は同期で動き、無駄がなくなりました。
念の為、時間を計測してパフォーマンスの違いを確認してみましょう。
ほんとにパフォーマンス上がるの?
計測して確認します。
データ取得はダミーデータでおなじみ、json placeholder を使用します。
※計測ごとに履歴やキャッシュは削除し、同じ条件下で計測しています。
以下、コードです。
await 3連発
import "./App.css";
function App() {
  const fetchData = async () => {
    const responseData = await fetch(
      "https://jsonplaceholder.typicode.com/posts"
    );
    const responseDataJson = await responseData.json();
    return responseDataJson;
  };
  const fetchData2 = async () => {
    const responseData = await fetch(
      "https://jsonplaceholder.typicode.com/comments"
    );
    const responseDataJson = await responseData.json();
    return responseDataJson;
  };
  const fetchData3 = async () => {
    const responseData = await fetch(
      "https://jsonplaceholder.typicode.com/albums"
    );
    const responseDataJson = await responseData.json();
    return responseDataJson;
  };
  const getUserData = async () => {
    // 計測開始
    const startTime = Date.now();
    // データ取得
    const responseData = await fetchData();
    const responseData2 = await fetchData2();
    const responseData3 = await fetchData3();
    // データ表示
    console.log(responseData);
    console.log(responseData2);
    console.log(responseData3);
    // 計測終了
    const endTime = Date.now();
    const time = endTime - startTime;
    console.log(`${time}ms`);
  };
  return (
    <div className="App">
      <button onClick={getUserData}>ボタン</button>
    </div>
  );
}
export default App;
計測結果
・Edge
初回→ 219 ms
2回目→ 64 ms
3回目→ 49 ms
・Chrome
初回→ 223 ms
2回目→ 82 ms
3回目→ 89 ms
もちろん、ちゃんとデータも取れています。

Promise.allで同期処理
計測結果
・Edge
初回→ 120 ms
2回目→ 26 ms
3回目→ 25 ms
・Chrome
初回→ 197 ms
2回目→ 30 ms
3回目→ 28 ms
もちろん、データも取れています。

まとめ
| ブラウザ/対象 | await 3連発 | Promise.allで同期処理 | 
| Edge 1回目 | 219 | 120 | 
| Edge 2回目 | 64 | 26 | 
| Edge 3回目 | 49 | 25 | 
| Chrome 1回目 | 223 | 197 | 
| Chrome 2回目 | 82 | 30 | 
| Chrome 3回目 | 89 | 28 | 
どのブラウザでも、何回目であっても同期処理の全勝でした。
今回は100個ほどのデータでしたが、
10000個くらいになると秒単位でかわってくるんじゃないかなーと思います。
フロントは早さが正義なので、
非同期処理を使う際は、ぜひこの記事を思い出してくださいね!
今回はここまで!
Enjoy Hacking!



