Introduction: Why Profile TypeScript?
TypeScript is a powerful tool for developing scalable applications, but even the most well-typed code can suffer from hidden performance issues. Bottlenecks arise from inefficient algorithms, excessive I/O operations, improper memory management, or slow computations. Profiling allows you to identify these areas and optimize them purposefully.
In this article, we will explore practical methods for profiling TypeScript code: from built-in browser tools to specialized utilities for Node.js. You will learn how to find slow functions, analyze the call stack, and make data-driven decisions.
TypeScript Profiling Tools
Profiling TypeScript code is no different from profiling JavaScript, since TypeScript compiles to JS. However, it is important to consider that the original TypeScript source code may contain additional abstractions (generics, decorators, interfaces) which, after compilation, can generate non-obvious patterns.
1. Chrome DevTools Performance
For frontend applications, the best choice is the Performance tab in Chrome DevTools. It records page activity and shows a flame chart, function execution time, events, and memory usage.
How to use:
- Open DevTools (F12) → Performance tab.
- Click the record button (circle), perform the desired action on the page.
- Stop the recording and study the flame chart.
Example: if you have an array processing function that takes longer than 100 ms, you will see it as a wide block on the graph. Click on it — DevTools will show the source code (if source maps are enabled) and the execution time.
// Original TypeScript codefunction processItems(items: number[]): number[] { return items .filter(x => x > 10) .map(x => x * 2) .reduce((acc, val) => acc + val, 0);}After profiling, you might see that filter and map create intermediate arrays, which slows down performance on large data sets. The optimization is to replace the chain with a single pass using for or reduce.
2. Node.js Built-in Profiler
For server-side Node.js code, use the built-in V8 profiler. It collects call stack samples and allows you to analyze which functions consume the most time.
Running:
node --prof your-compiled-file.jsAfter execution, a file named isolate-0x...-v8.log will be created. Convert it to a readable format:
node --prof-process isolate-0x...-v8.log > profile.txtIn the resulting file, you will see a table with columns: ticks (number of samples), total (total time), nonlib (time excluding libraries), and function name. Functions with the highest number of ticks are your candidates for optimization.
3. ts-node and Source Maps
When developing in TypeScript, ts-node is often used to run code without prior compilation. For profiling, ensure that source maps are enabled in tsconfig.json:
{ "compilerOptions": { "sourceMap": true, "inlineSourceMap": true }}Then launch the application with the --inspect flag:
node --inspect -r ts-node/register src/app.tsOpen Chrome and navigate to chrome://inspect. You will see your application and will be able to use DevTools for profiling, viewing the original TypeScript code instead of the compiled JavaScript.
Finding Bottlenecks: Practical Examples
Let's consider three typical scenarios where profiling helps find problems.
1. Slow Computations in a Loop
Suppose you have