Introducción: ¿Por qué perfilar TypeScript?
TypeScript es una herramienta poderosa para desarrollar aplicaciones escalables, pero incluso el código más tipificado puede sufrir problemas de rendimiento ocultos. Los cuellos de botella surgen de algoritmos ineficientes, operaciones de E/S excesivas, gestión inadecuada de memoria o cálculos lentos. El perfilado te permite identificar estas áreas y optimizarlas de manera deliberada.
En este artículo, exploraremos métodos prácticos para perfilar código TypeScript: desde herramientas integradas del navegador hasta utilidades especializadas para Node.js. Aprenderás cómo encontrar funciones lentas, analizar la pila de llamadas y tomar decisiones basadas en datos.
Herramientas de perfilado de TypeScript
Perfilar código TypeScript no es diferente a perfilar JavaScript, ya que TypeScript se compila a JS. Sin embargo, es importante considerar que el código fuente original de TypeScript puede contener abstracciones adicionales (genéricos, decoradores, interfaces) que, después de la compilación, pueden generar patrones no obvios.
1. Rendimiento de Chrome DevTools
Para aplicaciones frontend, la mejor opción es la pestaña Performance en Chrome DevTools. Registra la actividad de la página y muestra un gráfico de llama, tiempo de ejecución de funciones, eventos y uso de memoria.
Cómo usarlo:
- Abre DevTools (F12) → pestaña Performance.
- Haz clic en el botón de grabación (círculo), realiza la acción deseada en la página.
- Detén la grabación y estudia el gráfico de llama.
Ejemplo: si tienes una función de procesamiento de arrays que tarda más de 100 ms, la verás como un bloque ancho en el gráfico. Haz clic en ella — DevTools mostrará el código fuente (si los mapas de origen están habilitados) y el tiempo de ejecución.
// Original TypeScript codefunction processItems(items: number[]): number[] { return items .filter(x => x > 10) .map(x => x * 2) .reduce((acc, val) => acc + val, 0);}Después del perfilado, podrías ver que filter y map crean arrays intermedios, lo que ralentiza el rendimiento en conjuntos de datos grandes. La optimización es reemplazar la cadena con un solo paso usando for o reduce.
2. Perfilador integrado de Node.js
Para código del lado del servidor en Node.js, usa el perfilador V8 integrado. Recoge muestras de la pila de llamadas y te permite analizar qué funciones consumen más tiempo.
Ejecución:
node --prof your-compiled-file.jsDespués de la ejecución, se creará un archivo llamado isolate-0x...-v8.log. Conviértelo a un formato legible:
node --prof-process isolate-0x...-v8.log > profile.txtEn el archivo resultante, verás una tabla con columnas: ticks (número de muestras), total (tiempo total), nonlib (tiempo excluyendo librerías) y nombre de la función. Las funciones con el mayor número de ticks son tus candidatas para optimización.
3. ts-node y mapas de origen
Al desarrollar en TypeScript, a menudo se usa ts-node para ejecutar código sin compilación previa. Para el perfilado, asegúrate de que los mapas de origen estén habilitados en tsconfig.json:
{ "compilerOptions": { "sourceMap": true, "inlineSourceMap": true }}Luego inicia la aplicación con la bandera --inspect:
node --inspect -r ts-node/register src/app.tsAbre Chrome y navega a chrome://inspect. Verás tu aplicación y podrás usar DevTools para el perfilado, viendo el código TypeScript original en lugar del JavaScript compilado.
Encontrar cuellos de botella: ejemplos prácticos
Consideremos tres escenarios típicos donde el perfilado ayuda a encontrar problemas.
1. Cálculos lentos en un bucle
Supón que tienes