Profiling TypeScript Code: Finding Bottlenecks

Online Python Trainer for Beginners

Learn Python easily without overwhelming theory. Solve practical tasks with automatic checking, get hints in Russian, and write code directly in your browser — no installation required.

Start Course

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.js

After 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.txt

In 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.ts

Open 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

Blogs

Book Recommendations