Profiling and Source Maps

Profiling with DevTools; Source Maps

Profile before you optimize. In Chrome 1 's Performance panel (Network and Lighthouse), record while reproducing the slow interaction: wide bars in the flame chart took long, and the Bottom-Up tab ranks functions by self time (excluding callees). User Timing calls such as performance.measure('render', { start: 'load' }) appear in the Timings track, or on a custom track with detail: { devtools: { track: 'App' } }. For Node.js 2,131 , node --cpu-prof app.js writes a .cpuprofile file that the same panel imports.

Source maps

Production code is bundled and minified, so stack traces point at column 42 of a one-line file. A source map is a JSON file that maps positions in generated code back to the original file, line, column and name; the format was standardized as ECMA-426 in December 2024. Here is a two-file project with a bug:

src/cart.js and src/app.js: a bug to traceJavaScript
export function total(items) {                      // src/cart.js
  return items.reduce((sum, item) => sum + item.price * item.qty, 0);
}
import { total } from './cart.js';                  // src/app.js
console.log(total([{ price: 5, qty: 2 }, null]));

Bundle it with esbuild 126 (Build Tools and Bundlers), npx esbuild src/app.js --bundle --minify --sourcemap --platform=node --outfile=dist/app.js, then run node dist/app.js and node --enable-source-maps dist/app.js:

Output of 138
TypeError: Cannot read properties of null (reading 'price')
    at C:\shop\dist\app.js:1:42
    at t (C:\shop\dist\app.js:1:24)
TypeError: Cannot read properties of null (reading 'price')
    at <anonymous> (C:\shop\src\cart.js:2:49)
    at total (C:\shop\src\cart.js:2:16)

The output shows selected frames with the project path shortened: the minified function t becomes total in src/cart.js. esbuild ended dist/app.js with //# sourceMappingURL=app.js.map; the map holds version 3, sources, their text in sourcesContent, identifiers in names, and a mappings string starting AAAO,SAASA,EAAMC. Semicolons separate generated lines, commas separate segments, and each segment is Base64 VLQ numbers relative to the previous segment: generated column, source index, original line, column and optional name index. AAAO decodes to 0, 0, 0, 7: column 0 comes from sources[0], line 0, column 7 (function). DevTools applies maps automatically, so Sources breakpoints land on your original code.