前提知識
ブラウザとスレッド
連続して実行される一本の処理の流れ。
- 処理A
- 処理B
- 処理C
ブラウザのjavascriptに関わるスレッド
- Main Thread > JavaScriptが関わるスレッド
- Service Worker
- Web Worker
メインスレッド(Main Thread)
JavaScriptの実行とレンダリング(画面描写処理)を行う。
javascript => レンダリング
FPS(Flames Per Second)
1秒間あたりの画面(フレーム)更新頻度
- 1秒間に60回画面更新 => 60fps = 16.7秒に1回画面更新されている。
重い処理があると画面が更新されなくなる。
- JavaScript側で16.7ms以上かかる処理のケース
同期処理と非同期処理
同期処理
- メインスレッドでコードが順番に実行される。
- 1つの処理が完了するまで、次の処理には進まない。
- 重い処理があった場合は、処理が完了するまで次の処理に進まない。
case
- 3秒後に実行されるsleep関数を用意
- ブラウザーをロードした時に3秒後に
sleep done
が表示される。 - その後
button clicked
がレンダリングされコンソール状に表示されるようになる。 - 3秒間中にボタンを何回押しても'button clicked'が表示されないことに注目したい。
- かならず、
sleep done
が表示された後にbutton clicked
が表示される。 - すなわち、javascriptのスレッドが処理されている時には次の処理(レンダリング)がされていないことがわかる。
- ブラウザーをロードした時に3秒後に
function sleep(ms) {
const startTime = new Date();
while (new Date() - startTime < ms);
console.log('sleep done');
}
const btn = document.querySelector('button');
btn.addEventListener('click', function(){
console.log('button clicked');
});
sleep(3000);
case2(非同期処理)
- webAPIのsetTimeoutを使用して2秒後にsleep関数を実行する。
- sleep関数を実行するまでの2秒間にボタンを押す。
-
button clicked
が表示される。
-
- 3秒後にsleep done
- またその後にボタンを押すと
button clicked
が表示される。
- sleep関数を実行するまでの2秒間にボタンを押す。
- setTimeoutはjavascriptが占有するメインスレッドを解放されレンダリングが先に実行される。
- そして、3秒後にjavascriptがメインスレッドを占有し
sleep done
を表示する。 - すなわち、非同期処理とはjavascriptが一時的にメインスレッドから処理の解放されている時に実行されること
function sleep(ms) {
const startTime = new Date();
while (new Date() - startTime < ms);
console.log('sleep done');
}
const btn = document.querySelector('button');
btn.addEventListener('click', function(){
console.log('button clicked');
});
setTimeout(function(){
sleep(3000)
},2000)
非同期APIの例
-
setTimeout
-
Promise
-
queueMicrotask
-
etc...
-
UIイベントではクリックなども非同期として渡すことができる。
-
そのほか、NWイベント、i/oイベントなどがある。