O motor Turbolog
Como os quadros são codificados por comprimento de sequência em uma chamada console.log, além de CellBuffer, detalhes do Chromium e benchmarks.
Turbolog transforma cada commit do React em uma chamada a console.log, ou nenhuma se nenhuma célula mudou.
Objetivos
- Uma chamada por quadro alterado.
- Zero chamadas quando ocioso. Um quadro sem alterações retorna antes de construir uma string.
- Poucos argumentos de estilo. 149 spans
%cpara as 3.200 células de um painel denso de100×32.
Pipeline
React ─▶ Yoga ─▶ CellBuffer ─▶ row-hash gate ─▶ RLE ─▶ console.logCellBuffer
O quadro fica em arrays tipados planos para caracteres, cores e atributos, alocados uma única vez.
Filtro de alterações
Cada linha recebe um hash. Se nada mudou, o driver retorna antecipadamente:
if (frame === null) return SKIPPED; // 0 console callsconsole.log(frame.format, ...frame.args);Troca de quadros
Turbolog anexa quadros e limpa o console apenas no primeiro quadro, após invalidate(), quando ocioso depois de acumular 100 quadros, e aos 300. DevTools remove as mensagens apagadas de imediato, mas limita a pintura de novas mensagens a intervalos de 50 ms, então limpar a cada quadro faz o console vazio piscar. Os quadros anexados são trocados em uma única pintura, e um span de largura zero que funciona como cortina mantém o quadro anterior fora de vista. Role para cima para ver os quadros anteriores.
Os quadros são cadenciados a cerca de 15 fps. Quadros mais rápidos reiniciam o intervalo de limitação do DevTools e são descartados.
Codificação por comprimento de sequência
Células iguais se unem em um único span %c. Os spans continuam pelas quebras de linha, e as strings CSS são internadas.
console.log("%c▼ Text.js%c ready", "color:#ededed;font-weight:700", "color:#45a557");Detalhes do Chromium
- O
%literal é escapado como%%. - URLs e textos
path:linerecebem um word joiner para que o DevTools não altere seus estilos. - Os spans usam apenas propriedades CSS por extenso. DevTools copia cada propriedade expandida para cada linha.
- Os spans são ajustados para que os fundos se encaixem sem lacunas.
Firefox e Safari
Chromium dispõe cada linha de um span %c como um bloco inline. Firefox e Safari mantêm os spans inline, então ignoram margens verticais e quebram linhas longas. CssConsoleDriver detecta o navegador com testes de recursos CSS e, para esses dois consoles, define uma altura de linha de 14 px sem margens, desativa a quebra de linha com text-wrap-mode: nowrap e empurra quadros anteriores para fora de vista com uma cortina line-height: 100vh. O ajuste ao console reserva espaço para a coluna de links de origem do Firefox. Safari coloca Menlo em primeiro lugar na lista de fontes, porque suas páginas não podem usar uma SF Mono instalada pelo usuário que o Web Inspector pode usar para desenhar o texto. Passe browser para createConsoleRoot para escolher um console por conta própria.
Benchmarks
packages/core/test/perf.test.ts em um painel denso de 100×32, média de 1.000 quadros (Apple M5 Pro, Bun 1.4.4):
| Quadro | Tempo | Spans %c |
|---|---|---|
| Repintura completa (layout, pintura, codificação) | 0,163 ms | 149 |
| Edição de uma linha | 0,011 ms | 149 |
| Ocioso | 0,000 ms | 0 |
A página Status executa o mesmo pipeline no seu navegador. Execute text.stats() no DevTools enquanto uma demonstração do Playground estiver em execução.