こんにちは、なかにしです。
最近は本業も忙しいのですが、
引っ越しをしたのでさらに忙しくなっています。
引っ越し業者は高いですし、
気分転換も兼ねて家具を一新することにしたので、
最終的に段ボール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!