Согласно это вопрос StackOverflow
Изменение DOM происходит синхронно.Визуализация DOM на самом деле происходит после очистки стека JavaScript.
и в соответствии с this google doc скорость обновления экрана 60fps эквивалентна примерно обновлению каждые 16 мс, я пишу этот пример:
<!DOCTYPE html>
<html>
<head>
<script>
document.addEventListener('DOMContentLoaded', function() {
document.querySelector('#do').onclick = function() {
document.querySelector('#status').innerHTML = 'calculating...';
// setTimeout(long, 0); // will block
setTimeout(long, 1); // will not block
};
function long(){
let result = 0
for (let i = 0; i < 1000; i++) {
for (let j = 0; j < 1000; j++) {
for (let k = 0; k < 1000; k++) {
result += i + j + k;
}
}
}
document.querySelector('#status').innerHTML = 'calculation done';
document.querySelector('#result').innerHTML = result.toString();
}
});
</script>
</head>
<body>
<button id='do'> Do long calc!</button>
<div id='status'></div>
<div id='result'></div>
</body>
</html>
с jsfiddle link
Я поигрался с кодом и обнаружил, что блокировка происходит с задержкой менее 12 мс и чаще с меньшей задержкой.
У меня есть два разных способа понимания:
В этом случае только setTimeout
с задержкой более 16 мс не должны блокироваться, задержка 0 и 1 - это путьменее 16 мс, поэтому они оба должны блокироваться;
Сразу после вызова setTimeout
и long
отправлены в очередь сообщений (с необязательной задержкой), теперь стек вызовов пуст, поэтому воба случая setTimeout
не должны блокироваться, и «вычисление ...» всегда должно отображаться.
Что не так с моим пониманием?