FNSP Web Page

O event loop: porque é que um ciclo bloqueia a página inteira

O JavaScript tem uma thread só. É a mesma que corre o seu código, responde aos cliques e desenha a página — e é por isso que um ciclo pesado congela tudo, incluindo o cursor a piscar numa caixa de texto.

1. O modelo, em três peças

  • A pilha — o que está a correr agora. Uma coisa de cada vez.

  • As tarefas — o que está à espera de vez: um setTimeout que expirou, um clique, uma resposta da rede.

  • As microtarefas — as continuações de promessas. Têm fila própria, e prioridade.

O ciclo é simples: correr até a pilha esvaziar, esvaziar toda a fila de microtarefas, e só então pegar na tarefa seguinte.

2. A ordem que confunde toda a gente

console.log('1');

setTimeout(() => console.log('2'), 0);

Promise.resolve().then(() => console.log('3'));

console.log('4');

// 1, 4, 3, 2

O setTimeout com zero não quer dizer "já": quer dizer "põe na fila das tarefas". A promessa vai para a fila das microtarefas, que é esvaziada primeiro — daí o 3 antes do 2.

3. Onde isto morde

// Meio segundo em que nada responde: nem cliques, nem scroll, nem animações
const resultado = listaDeCemMil.map(calculoPesado);

A pilha não esvazia enquanto o map não acabar, portanto o browser não chega a desenhar nada. É exatamente isto que a métrica INP mede.

4. As saídas

Partir o trabalho, para o browser respirar entre pedaços:

async function emPedacos(itens, tarefa, tamanho = 500) {
  for (let i = 0; i < itens.length; i += tamanho) {
    itens.slice(i, i + tamanho).forEach(tarefa);
    // Devolve a vez ao browser: ele desenha, responde, e continua
    await new Promise((resolve) => setTimeout(resolve, 0));
  }
}

Ou tirá-lo da thread principal de vez, com um worker:

const trabalhador = new Worker('./calculo.js');
trabalhador.postMessage(listaDeCemMil);
trabalhador.addEventListener('message', (e) => mostrar(e.data));

E a nota que fecha o assunto: async não é paralelismo. Um await liberta a thread enquanto espera por algo — rede, disco, um temporizador. Não a liberta enquanto calcula.

Comentários

Ainda ninguém comentou este artigo.

Voltar ao blog

Gostávamos de saber quantas pessoas visitam o site, com o Google Analytics. Sem a sua autorização não corre nada. Política de Privacidade.