Parcel 28 ๐ฆ Performance Analysis โ Bundle reports & build profiling
Parcel’s performance analysis has two distinct surfaces: the bundle report that tells you what the output contains, and the build trace that tells you where the time went. They are not the same tool, and they answer different questions. The bundle report is generated automatically at the end of a production build, and it is more accurate in Parcel 2 than it was in Parcel 1 because it is based on source maps and excludes the code that tree shaking and minification removed . The build trace is opt-in, it is written to a JSON file, and it is analysed with Perfetto or a SQL query rather than a treemap .
The bundle report is the first thing to check when the output is larger than expected. It shows the size of each bundle and the assets that compose it. The report is in the CLI output, and it is based on the source maps rather than the raw file sizes, which means a bundle that was tree-shaken down to a small fraction of its original code is reported at the smaller size . The second thing to check is the trace, which shows the time spent in each phase of the build and the plugins that consumed the most time.
Key point: The bundle report is automatic and CLI-based; it shows the composition and size of the output. The build trace is opt-in via --trace, it is a JSON file, and it is analysed with Perfetto for SQL-based queries of phase and plugin durations. The two are complementary: the report tells you what shipped, and the trace tells you why the build took as long as it did.
Why the two surfaces are separate
The bundle report problem. The output of a Parcel build is a set of bundles, and the report is the summary of what each bundle contains. The report is generated at the end of a production build, and it is more accurate in Parcel 2 because the source maps preserve the location information through the tree-shaking and minification steps . The report does not tell you which plugin took the most time; it tells you what the output looks like after all the plugins have run.
The build trace problem. The trace is a record of the build’s execution. It tracks the phasesโbuilding, bundling, packaging, optimizingโand the plugins that were called in each phase, and how long each call took . The trace answers questions that the bundle report cannot: which plugin is the bottleneck, which file takes the longest to transform, and which phase dominates the build time. The trace is opt-in because the JSON file can be large, and the overhead is non-zero, though it is less expensive than a CPU sampling profile .
The analysis tool problem. The bundle report is a CLI output that a human reads. The trace is a JSON file that is analysed with Perfetto, which loads the data into an SQLite database and allows SQL queries against it . The trace is not a visualization in the way the bundle report is; it is a dataset that the developer queries. The parcel-plugin-bundle-visualiser is the third-party alternative that produces a treemap of the bundle contents, but it is a plugin for the older Parcel 1 and is not the official Parcel 2 surface .
The trade-off. The bundle report is free and automatic, but it only shows the output. The trace costs an opt-in flag and a large JSON file, but it shows the process. A project that is troubleshooting a large bundle uses the report first, and a project that is troubleshooting a slow build uses the trace first. The two tools are not interchangeable, and the audit is the discipline of using the right one for the question.
a. The bundle report and the composition audit
The bundle report is generated automatically when the production build completes. It is based on the source maps, which means the sizes are the post-tree-shaking and post-minification sizes rather than the pre-processing sizes . The report is in the CLI output, and it lists each bundle with its size and the assets that compose it.
# The production build generates the bundle report.
parcel build index.html
# The report appears at the end of the build output.
# It lists the bundles and their sizes.
The parcel-plugin-bundle-visualiser is the third-party treemap tool for a more visual composition analysis. It is installed as a dev dependency and generates a report.html file in the output directory when the production build runs. The treemap shows each asset as a rectangle proportional to its size, and the hover tooltip shows the asset’s path, size, and estimated gzip size .
# Install the visualizer (third-party, for a treemap view)
npm install --save-dev parcel-plugin-bundle-visualiser
# Run the production build.
parcel build index.html
# The report is at dist/report.html.
The visualizer is useful for finding the largest assets in the bundle, but it is not the official Parcel 2 analysis surface. The official surface is the CLI report, and the visualizer is the community tool for the treemap view.
b. The build trace and the phase audit
The build trace is enabled with the --trace flag. Parcel writes a JSON file to the project root and logs the filename when the build starts. The trace uses the Chrome Tracing Format, and it consists of complete events (ph: "X") with a timestamp, a duration, a category, and a name .
# Generate the trace.
parcel build index.html --trace
# Parcel logs the trace filename at the start of the build.
# The file is written to the project root.
The API form is the shouldTrace: true option plus the @parcel/reporter-tracer reporter in the additionalReporters array. The reporter is the component that writes the JSON file .
// The API form of the trace
import { Parcel } from '@parcel/core';
const bundler = new Parcel({
entries: 'index.html',
shouldTrace: true,
additionalReporters: [
{
packageName: '@parcel/reporter-tracer',
resolveFrom: __dirname,
},
],
});
await bundler.run();
The trace is analysed with Perfetto, which is a Google tool designed for large traces and non-browser data. Perfetto loads the trace into an SQLite database, and the developer queries it with SQL. The Vite documentation provides the example queries for the phase breakdown and the plugin duration breakdown .
-- The phase breakdown query
select
name, SUM(CAST(dur AS double)/1000/1000) as dur_ms
from
slice s
where
s.category = "Core"
group by name
order by dur_ms desc
The query returns the total duration for each core phaseโbuilding, bundling, packagingโin milliseconds. The durations are the sampled time, which may exceed the wall time because Parcel is multi-threaded . The plugin query is the second useful query: it groups the events by category and name to show which plugins consumed the most time.
The --trace flag was added in Parcel 2.9.0, and it is the official profiling surface. The PARCEL_PROFILE environment variable is the older profiling mechanism, and it requires the inspector module, which is not available in every Node.js distribution . The --trace flag is the recommended approach for a build-phase analysis.
Complete Example Session
// ============================================
// PART 1: THE BUNDLE REPORT
// ============================================
// parcel build index.html
//
// The report is at the end of the CLI output.
// It is based on the source maps.
// It excludes the tree-shaken and minified code.
// The sizes are the post-processing sizes.
// ============================================
// PART 2: THE BUNDLE VISUALIZER
// ============================================
// npm install --save-dev parcel-plugin-bundle-visualiser
// parcel build index.html
//
// The report is at dist/report.html.
// The treemap shows the assets by size.
// The hover tooltip shows the path, size, and gzip estimate.
// ============================================
// PART 3: THE TRACE FLAG
// ============================================
// parcel build index.html --trace
//
// The trace JSON file is written to the project root.
// Parcel logs the filename at the start of the build.
// The file uses the Chrome Tracing Format.
// ============================================
// PART 4: THE API TRACE
// ============================================
// The API form:
import { Parcel } from '@parcel/core';
const bundler = new Parcel({
entries: 'index.html',
shouldTrace: true,
additionalReporters: [
{ packageName: '@parcel/reporter-tracer', resolveFrom: __dirname },
],
});
await bundler.run();
// The shouldTrace option enables the events.
// The reporter writes the JSON file.
// ============================================
// PART 5: THE PERFETTO ANALYSIS
// ============================================
// Open the trace in Perfetto (ui.perfetto.dev).
// The trace is loaded into an SQLite database.
// The "Query (SQL)" function runs the queries.
// ============================================
// PART 6: THE PHASE BREAKDOWN QUERY
// ============================================
// The query for the phase breakdown:
select
name, SUM(CAST(dur AS double)/1000/1000) as dur_ms
from
slice s
where
s.category = "Core"
group by name
order by dur_ms desc
// The result shows the building, bundling, packaging,
// and optimizing phases with their durations.
// ============================================
// PART 7: THE PLUGIN BREAKDOWN QUERY
// ============================================
// The query for the plugin breakdown:
select
s.category, name, SUM(CAST(dur AS double)/1000/1000) as dur_ms
from
slice s
where
s.category = "transform"
group by name
order by dur_ms desc
// The result shows which transformers consumed the most time.
// ============================================
// PART 8: THE PARCEL_PROFILE ALTERNATIVE
// ============================================
// The older profiling mechanism:
// PARCEL_PROFILE=true parcel build index.html
//
// It requires the Node.js inspector module.
// It is not available in every Node.js distribution.
// The --trace flag is the recommended approach.
// ============================================
// PART 9: THE PERFORMANCE CONTEXT
// ============================================
// Parcel 2 uses SWC for the JavaScript transform.
// SWC is 20x faster than Babel .
// The scope hoisting linker operates on strings, not ASTs .
// The build is up to 10x faster than Parcel 1 .
// The trace shows where the remaining time is spent.
// ============================================
// PART 10: THE CHECKLIST
// ============================================
// [ ] The bundle report is checked after the production build.
// [ ] The visualizer is used for a treemap view if needed.
// [ ] The --trace flag is used for a build-phase analysis.
// [ ] The trace is opened in Perfetto.
// [ ] The phase breakdown query is run.
// [ ] The plugin breakdown query is run.
// [ ] The PARCEL_PROFILE alternative is used only if the inspector is available.
The ten parts covered the bundle report, the visualizer, the trace flag, the API trace, the Perfetto analysis, the phase query, the plugin query, the PARCEL_PROFILE alternative, the performance context, and the checklist. The through-line is that the bundle report is the output audit and the trace is the process audit.
Quick Reference
The bundle report
| Aspect | Detail |
|---|---|
| Generation | Automatic, production build |
| Accuracy | Based on source maps, post-tree-shaking |
| Output | CLI report |
| Treemap | parcel-plugin-bundle-visualiser (third-party) |
The build trace
| Aspect | Detail |
|---|---|
| Flag | --trace |
| API option | shouldTrace: true |
| Reporter | @parcel/reporter-tracer |
| Format | Chrome Tracing Format (JSON) |
| Analysis tool | Perfetto (SQL queries) |
The key queries
| Query | Purpose |
|---|---|
| Phase breakdown | where category = "Core" |
| Plugin breakdown | where category = "transform" |
Best Practices
โ Do This:
# Check the bundle report after the production build
parcel build index.html // โ
# Use the trace for a slow-build investigation
parcel build index.html --trace // โ
# Analyse the trace in Perfetto with the phase query
// The query shows the dominant phase. // โ
โ Don’t Do This:
# Use PARCEL_PROFILE on a Node.js distribution without the inspector
PARCEL_PROFILE=true parcel build index.html // may fail // โ
# Assume the bundle report shows the pre-minification sizes
// The report is based on the source maps. // โ
Common Pitfalls
| Pitfall | Why It Happens | Fix |
|---|---|---|
| The trace file is huge | The trace records every event | Use it for targeted investigations, not every build |
PARCEL_PROFILE fails | The inspector module is unavailable | Use --trace instead |
| The bundle report is inaccurate | The source maps are disabled | Ensure the source maps are generated |
| The plugin query returns nothing | The category name is wrong | Use the transform category |
Real-World Examples
1. The bundle report
parcel build index.html
2. The visualizer
npm install -D parcel-plugin-bundle-visualiser && parcel build index.html
3. The trace
parcel build index.html --trace
4. The API trace
new Parcel({ shouldTrace: true, additionalReporters: [{ packageName: '@parcel/reporter-tracer', resolveFrom: __dirname }] })
5. The phase query
select name, SUM(CAST(dur AS double)/1000/1000) as dur_ms from slice s where s.category = "Core" group by name order by dur_ms desc
6. The plugin query
select s.category, name, SUM(CAST(dur AS double)/1000/1000) as dur_ms from slice s where s.category = "transform" group by name order by dur_ms desc
7. The Perfetto URL
https://ui.perfetto.dev/
8. The PARCEL_PROFILE alternative
PARCEL_PROFILE=true parcel build index.html
9. The visualizer output
dist/report.html
10. The trace output
parcel-trace-<timestamp>.json
Visual
The Two Analysis Surfaces
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ BUNDLE REPORT VS BUILD TRACE โ
โ โ
โ Bundle report Build trace โ
โ โโโโโโโโโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ What shipped โ โ Where the time went โ โ
โ โ Automatic โ โ Opt-in (--trace) โ โ
โ โ CLI output โ โ JSON file โ โ
โ โ Source-map based โ โ Perfetto analysis โ โ
โ โโโโโโโโโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ
โ The report audits the output. โ
โ The trace audits the process. โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
The Trace Analysis Flow
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ FROM TRACE TO QUERY โ
โ โ
โ parcel build --trace โ
โ โ โ
โ โผ โ
โ โโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ The trace JSON file โ Chrome Tracing Format โ
โ โโโโโโโโโโโโฌโโโโโโโโโโโ โ
โ โ โ
โ โผ โ
โ โโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ Perfetto โ Loads into SQLite โ
โ โ ui.perfetto.dev โ โ
โ โโโโโโโโโโโโฌโโโโโโโโโโโ โ
โ โ โ
โ โผ โ
โ โโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ SQL query โ Phase breakdown โ
โ โ โ Plugin breakdown โ
โ โโโโโโโโโโโโโโโโโโโโโโโ โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
The Phase Breakdown
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ THE QUERY SHOWS THE DOMINANT PHASE โ
โ โ
โ Building: โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ 1200ms โ
โ Bundling: โโโโโโโโ 300ms โ
โ Packaging: โโโโโโ 200ms โ
โ Optimizing: โโโโโโโโโโโโโโ 500ms โ
โ โ
โ The building phase dominates. โ
โ The plugin query shows which transformer is responsible. โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
Summary
| Item | Value |
|---|---|
| Bundle report | Automatic, source-map based, CLI output |
| Treemap | parcel-plugin-bundle-visualiser (third-party) |
| Build trace | --trace flag, JSON file |
| Trace format | Chrome Tracing Format |
| Analysis tool | Perfetto (SQL queries) |
| Phase query | where category = "Core" |
| Plugin query | where category = "transform" |
| Older profiling | PARCEL_PROFILE (requires inspector) |
Key takeaways:
- The bundle report and the build trace answer different questions. The bundle report is the composition audit: it shows what the output contains and how large each bundle is. It is automatic, it is based on the source maps, and it excludes the tree-shaken and minified code . The build trace is the process audit: it shows where the time went, which phases dominated, and which plugins consumed the most time .
- The trace is opt-in and Perfetto-analysed. The
--traceflag writes a JSON file in the Chrome Tracing Format, and the file is opened in Perfetto, which loads it into an SQLite database. The SQL queries for the phase breakdown and the plugin breakdown are the two starting points . - The
PARCEL_PROFILEvariable is the older mechanism. It requires the Node.jsinspectormodule, which is not available in every distribution. The--traceflag is the recommended approach for a build-phase analysis . - The visualizer is the third-party treemap tool.
parcel-plugin-bundle-visualisergenerates areport.htmlwith a treemap of the bundle contents, and it is useful for a visual composition audit. It is not the official Parcel 2 analysis surface . - The performance context is the SWC rewrite. Parcel 2 uses SWC for the JavaScript transform, which is 20ร faster than Babel, and the scope hoisting linker operates on strings rather than ASTs. The build is up to 10ร faster than Parcel 1, and the trace shows where the remaining time is spent .
Remember: Parcel’s performance analysis has two tools: the bundle report and the build trace. The bundle report is automatic and shows what shipped. The build trace is opt-in and shows where the time went. The report is the CLI output; the trace is a JSON file analysed in Perfetto. The report is for the composition audit; the trace is for the phase and plugin audit. The two are complementary, and the audit is the discipline of using the right one for the question.
Stop using slow, ad-bloated tool sites! ๐คฎ
๐ Search “KandZ Tools” on Google to use many professional utilities for free.
KandZ.me is the ultimate minimalist hub for:
โ
Finance (Mortgage, Interest, Inflation)
โ
Tech (Base64, JSON, Dev Suite, IP)
โ
Health (BMI, BMR, TDEE)
โ
Productivity (Timer, Workspace, QR)
โก๏ธ Fast & Private
๐ No data leaves your device
๐ 100% Free
๐ Use it now: https://tools.kandz.me
๐ Bookmark itโyouโll need it later!