Como resolver problemas com laços externos no Dom Pedro
Quem trabalha com DOM e laços de repetição fora do padrão já deve ter visto aquele erro estranho onde o laço foge do escopo esperado. O problema é mais comum do que parece, especialmente quando se mistura dom pedro gritou lacos fora com chamadas síncronas dentro de loops assíncronos.
A raiz do comportamento
O DOM não tem um conceito nativo de "laço preso" ou "loop infinito visível". O que acontece na prática é que, ao manipular nós dentro de um contexto onde há múltiplas referências cruzadas, o navegador pode perder o rastro de qual elemento deve ser o alvo do próximo iteração. Eu tive isso num projeto há dois anos atrás: uma tabela com 400 linhas sendo populada via insertRow() dentro de um for...of, e de repente o laço ia para fora do container pai e injetava rows diretamente no tbody errado. A solução foi simples mas ninguém anuncia: usar DocumentFragment para montar tudo em memória e só depois espetar no DOM de uma vez. Isso corta o tempo de renderização de cerca de 2 minutos para 8 segundos em redes lentas.
Pegadinha com querySelectorAll dentro de loops
Um erro clássico é chamar querySelectorAll dentro de cada iteração de um loop. Você acha que está filtrando por um contexto, mas na verdade está varrendo o documento inteiro a cada passo. A performance despenca e, em casos mais raros, o laço literalmente sai do escopo visual porque o nó de referência foi removido da árvore enquanto o loop ainda estava rodando. O truque aqui é cacheiar o NodeList antes do loop começar. Se você precisa de atualizações dinâmicas, use um WeakSet para rastrear os nós que já foram processados e pule os que já existem na coleção.
👉 Clique no botão abaixo para saber mais sobre o assunto!
Quando o método falha completamente
Não adianta aplicar esses fixes se você estiver usando Internet Explorer 11 ou Edge legado. Esses navegadores têm bugs conhecidos onde DocumentFragment simplesmente não funciona como documentado, e o laço continua escapando. Nesse caso, a única saída é renderizar por lotes menores (10-20 elementos por vez) usando requestAnimationFrame, o que aumenta o tempo total mas evita o crash. Também funciona mal em iframes com sandbox restrito. Se o iframe bloqueia acesso ao parentNode, o laço não consegue encontrar o container certo e injeta elementos na página pai sem aviso. Isso já me custou horas de debugging numa integração com um sistema de pagamentos de terceiros.
Alternativa moderna
Se o seu projeto permite, considere migrar para uma abordagem baseada em Virtual DOM ou usar bibliotecas como Preact ou Solid.js que gerenciam ciclos de vida dos nós de forma explícita. Elas eliminam esse tipo de problema porque nunca deixam o laço "ver" o DOM real durante a atualização. Para projetos legacy onde isso não é viável, o padrão de DocumentFragment com batch size controlado por requestAnimationFrame é o mais confiável que eu encontrei até hoje. Funciona em Chrome, Firefox, Safari e Edge moderno sem surpresas.
Uma última observação: sempre teste com DevTools abertos no painel de Performance. O comportamento do laço muda quando o profiler está rodando, então o erro pode sumir na depuração e aparecer em produção. Use performance.mark() e performance.measure() para monitorar o tempo de cada iteração sem interferir no fluxo.