Perfilamento de código TypeScript: encontrando gargalos na prática

Treinador Online de Python para Iniciantes

Aprenda Python facilmente sem sobrecarga teórica. Resolva tarefas práticas com verificação automática e escreva código diretamente no navegador.

Start Course

Perfilamento de código TypeScript: encontrando gargalos na prática

\n

Todo desenvolvedor já se deparou com uma situação em que a aplicação começa a ficar lenta e a causa não é óbvia. No mundo do TypeScript, onde o código é transpilado para JavaScript, gargalos podem surgir tanto em tempo de execução quanto devido às características da própria transpilação. Neste artigo, vamos explorar métodos práticos de perfilamento de código TypeScript que ajudarão a identificar trechos problemáticos e melhorar o desempenho da sua aplicação.

\n\n

Por que o perfilamento de TypeScript é importante?

\n

TypeScript adiciona tipagem estática, mas em tempo de execução é executado JavaScript comum. Isso significa que os gargalos podem estar relacionados não apenas a algoritmos, mas também à forma como o TypeScript é compilado. Por exemplo, o uso excessivo de decoradores ou genéricos complexos pode gerar código não otimizado. O perfilamento ajuda a responder perguntas como:

\n
    \n
  • Quais funções demoram mais para executar?
  • \n
  • Quanta memória a aplicação consome?
  • \n
  • Onde ocorrem coletas de lixo frequentes?
  • \n
  • Quais trechos de código bloqueiam a thread principal?
  • \n
\n

Sem perfilamento, você corre o risco de otimizar os trechos errados, perdendo tempo com micro-otimizações que não trarão ganhos significativos.

\n\n

Ferramentas para perfilamento de TypeScript

\n

Para perfilamento de código TypeScript, usaremos três ferramentas principais que cobrem a maioria dos cenários: desde aplicações no navegador até soluções server-side com Node.js.

\n\n

1. Chrome DevTools para aplicações no navegador

\n

A ferramenta mais acessível e poderosa. Abra a aba Performance no Chrome DevTools, inicie a gravação e execute a ação desejada na aplicação. Após parar, você obterá um flame chart — uma representação visual das chamadas de função. Veja como funciona na prática:

\n
// Exemplo de código lento em TypeScript\nfunction processData(data: number[]): number[] {\n    const result: number[] = [];\n    for (let i = 0; i < data.length; i++) {\n        // Gargalo potencial: chamadas frequentes\n        result.push(data[i] * Math.sqrt(data[i]));\n    }\n    return result;\n}\n\n// Uso\nconst largeArray = Array.from({ length: 100000 }, (_, i) => i);\nconsole.time('processData');\nprocessData(largeArray);\nconsole.timeEnd('processData'); // ~15ms\n
\n

No Chrome DevTools, você verá que a função processData consome um tempo significativo, e dentro dela, várias chamadas a Math.sqrt. Isso indica que você pode substituir a iteração por map ou vetorizar os cálculos.

\n\n

2. Node.js profiler para aplicações server-side

\n

O Node.js possui um profiler embutido. Execute a aplicação com a flag --prof:

\n
node --prof dist/app.js\n
\n

Após a execução, será gerado um arquivo isolate-*.log. Converta-o para um formato legível:

\n
node --prof-process isolate-*.log > processed.txt\n
\n

Um exemplo de problema típico são alocações frequentes em loops:

\n
// Exemplo ruim: criação de objetos em loop\ninterface User {\n    id: number;\n    name: string;\n}\n\nfunction createUsers(ids: number[]): User[] {\n    const users: User[] = [];\n    for (const id of ids) {\n        users.push({ id, name: `User_${id}` }); // Nova alocação\n    }\n    return users;\n}\n
\n

O profiler mostrará que a função createUsers cria muitos objetos temporários, aumentando a carga no coletor de lixo. Otimização: alocar memória antecipadamente ou usar um pool de objetos.

\n\n

3. Benchmark.js para microbenchmarks

\n

Quando precisar comparar o desempenho de duas implementações, use a biblioteca benchmark.js. Instale-a via npm:

\n
npm install benchmark @types/benchmark\n
\n

Exemplo de comparação de duas formas de filtrar um array:

\n
import Benc                

Blogs

Book Recommendations