Performance em TypeScript
Baixar PDFOtimização de compilação, bundle size, tree shaking, type-only imports e o TypeScript nativo em Go (10x mais rápido).
Performance em TypeScript
Performance em TypeScript opera em três camadas: compilação (velocidade do tsc), bundle (tamanho do JS emitido) e runtime (execução no browser/Node.js). Cada camada tem otimizações específicas.
1. Otimização do tsconfig.json
Flags essenciais para compilação rápida
// tsconfig.json — configuração otimizada
{
"compilerOptions": {
// Paralelismo e cache
"isolatedModules": true, // permite compilação paralela (obrigatório com esbuild/SWC)
"incremental": true, // recompila apenas o que mudou
"tsBuildInfoFile": ".tsbuildinfo",
// Pula verificações desnecessárias
"skipLibCheck": true, // ignora .d.ts de node_modules (~30% mais rápido)
"skipDefaultLibCheck": true,
// Módulos otimizados
"moduleResolution": "bundler", // resolução moderna para bundlers
"verbatimModuleSyntax": true, // force `import type` — elimina imports do emit
"module": "esnext",
// Target moderno = JS menor
"target": "es2022", // async/await nativo, sem polyfills
"lib": ["es2022", "dom", "dom.iterable"]
}
}isolatedModules: true
Essa flag permite que cada arquivo seja transpilado independentemente, sem depender de informações de outros arquivos. Isso é essencial para:
- esbuild — 100x mais rápido que tsc para transpilação
- SWC — usado pelo Next.js, Rust-based
- Bun — bundler nativo em Zig
// ❌ Com isolatedModules, isso gera erro:
const enum Direction { Up, Down } // const enum não pode ser usado entre arquivos
// ✅ Use as const assertion:
const Direction = { Up: 0, Down: 1 } as const;2. Tree Shaking e Bundle Size
verbatimModuleSyntax + import type
O TypeScript 5.0+ introduziu verbatimModuleSyntax que substitui importsNotUsedAsValues. Ele força que imports de tipos usem import type, garantindo que sejam eliminados do JavaScript emitido.
// ❌ Import de tipo sem `type` — pode ser incluído no bundle
import { User, ApiResponse } from './types';
// ✅ Import de tipo — eliminado pelo bundler
import type { User, ApiResponse } from './types';
// ✅ Mix: tipos com `type`, valores sem
import { UserService } from './services';
import type { User, ApiResponse } from './types';Barrel exports e tree shaking
Barrel files (index.ts com export *) podem impedir tree shaking. O bundler não consegue eliminar exports não usados quando tudo passa por um barrel.
// ❌ index.ts — barrel que impede tree shaking
export * from './userService';
export * from './orderService';
export * from './paymentService'; // mesmo que só userService seja usado, tudo é incluído
// ✅ Imports diretos — bundler elimina o que não é usado
import { UserService } from './userService';
// ✅ Barrel com exports nomeados (melhor que wildcard)
export { UserService } from './userService';
export { OrderService } from './orderService';const enum vs enum vs as const
// ❌ enum — gera objeto IIFE no runtime (~100 bytes)
enum Direction { Up, Down, Left, Right }
// ✅ const enum — inlined pelo compilador, zero runtime
// Porém: não funciona com isolatedModules
const enum Direction { Up, Down, Left, Right }
// ✅✅ as const — zero runtime, funciona com isolatedModules, tree-shakeable
const Direction = { Up: 0, Down: 1, Left: 2, Right: 3 } as const;
type Direction = (typeof Direction)[keyof typeof Direction];preserveConstEnums + isolatedModules
// tsconfig.json
{
"compilerOptions": {
"isolatedModules": true,
"preserveConstEnums": false // remove const enums do emit
}
}3. Compilation speed — Projeto TypeScript Nativo em Go
Em março de 2025, Anders Hejlsberg anunciou o port nativo do TypeScript para Go. Este é o maior projeto de performance da história do TypeScript.
Benchmarks reais
| Codebase | Linhas de código | tsc atual (JS) | TS nativo (Go) | Speedup |
|---|---|---|---|---|
| VS Code | 1.505.000 | 77,8s | 7,5s | 10.4x |
| Playwright | 356.000 | 11,1s | 1,1s | 10.1x |
| TypeORM | 270.000 | 17,5s | 1,3s | 13.5x |
Benefícios além da compilação
- Editor: load de 9.6s → 1.2s no repositório do VS Code (8x mais rápido)
- Memória: ~50% de redução no uso de RAM
- Type checking paralelo: aproveita todos os cores da CPU
- LSP nativo: comunicação mais rápida com editores
Cronograma
- TypeScript 6.x — release de transição (JS, com deprecations para preparar o 7.0)
- TypeScript 7.0 — port nativo em Go, 100% compatível com a linguagem atual
- Preview disponível:
npm install @typescript/native-preview - Repositório: microsoft/typescript-go
4. Project References para monorepos
Para projetos grandes, project references permitem compilar apenas o que mudou, em ordem correta.
// tsconfig.json (raiz)
{
"references": [
{ "path": "./packages/shared" },
{ "path": "./packages/api" },
{ "path": "./packages/web" }
],
"compilerOptions": { "composite": true }
}# Compila apenas pacotes alterados
tsc --build --incremental
# Compila em paralelo (TS 5.0+)
tsc --build --force5. Runtime performance
Evite Object.keys() em loops quentes
// ❌ Aloca array a cada iteração
for (const key of Object.keys(config)) { /* ... */ }
// ✅ Cacheie as keys
const keys = Object.keys(config);
for (const key of keys) { /* ... */ }
// ✅✅ Use for...in com hasOwnProperty
for (const key in config) {
if (Object.prototype.hasOwnProperty.call(config, key)) { /* ... */ }
}Lazy imports para code splitting
// ❌ Import estático — carrega tudo no bundle inicial
import { HeavyChart } from './HeavyChart';
// ✅ Dynamic import — carrega apenas quando necessário
const HeavyChart = lazy(() => import('./HeavyChart'));
// ✅✅ Preload no hover — carrega antes do clique
const loadChart = () => import('./HeavyChart');
<a href="/chart" onMouseEnter={loadChart}>Ver gráfico</a>Map sobre Array para lookups
// ❌ O(n) — percorre array toda vez
const user = users.find(u => u.id === targetId);
// ✅ O(1) — lookup instantâneo
const userMap = new Map(users.map(u => [u.id, u]));
const user = userMap.get(targetId);6. Ferramentas de análise
| Ferramenta | O que faz | Comando |
|---|---|---|
tsc --generateTrace | Gera trace de performance do compilador | tsc --generateTrace ./trace |
source-map-explorer | Visualiza bundle por módulo | npx source-map-explorer dist/*.js |
webpack-bundle-analyzer | Visualiza bundle webpack | Plugin no next.config.js |
@typescript/analyze-trace | Analisa trace do tsc | npx @typescript/analyze-trace ./trace |
knip | Encontra exports/imports mortos | npx knip |
ts-unused-exports | Encontra exports não usados | npx ts-unused-exports tsconfig.json |
7. TypeScript 6.0 — Mudanças de performance
strict: truepor padrão — catches bugs cedo, reduz debugging--stableTypeOrdering— ordenação determinística de tipos (preparação para TS 7.0 paralelo)--target es2025— JS emitido é mais moderno e menor- Deprecated
--outFile— concatenar tudo em um arquivo impede tree shaking - Deprecated
--moduleResolution classic/node10— resolução lenta
Referências
- A 10x Faster TypeScript — Anders Hejlsberg (Microsoft Blog)
- Announcing TypeScript Native Previews (May 2025)
- Hacking Performance: TypeScript Tricks (FSJS.dev)
- Compiling for Performance: TypeScript Transpilation (OverCtrl)
- Mastering TypeScript Tree-Shaking (CodeZup)
- 7 Hidden TypeScript Compiler Optimizations (Stackademic)
- TypeScript Compilation & Runtime Optimization (AgileStack, Mar 2026)
- TypeScript Performance: Compilation Speed (Dakic)
- TypeScript 6.0 Release Notes
- microsoft/typescript-go (GitHub)