A page can finish downloading its critical resources and still remain slow because the browser is busy executing JavaScript, recalculating styles, laying out the page, painting or processing interactions.
A Chrome Performance Trace helps show what the browser was doing during that delay.
The goal is not to inspect every event in the Performance panel. The goal is to start from the user-visible symptom, locate the relevant time window and identify the work that may have prevented the browser from rendering or responding sooner.
What is a Chrome Performance Trace used for?
A Chrome Performance Trace records browser activity over time, including main-thread JavaScript, style calculation, layout, rendering and user interactions. It is useful when network timing alone cannot explain why a page renders or responds slowly. The trace helps identify expensive work and form a root-cause hypothesis that can then be tested and verified.
What a Performance Trace Can Tell You
A Performance Trace is a timeline of browser activity.
It can help answer questions such as:
- Was the main thread busy while the user was waiting?
- Which tasks occupied the browser for the longest periods?
- Was JavaScript executing before an important paint?
- Did style recalculation or layout consume significant time?
- Did an interaction arrive while the main thread was already occupied?
- Did a third-party script contribute meaningful CPU work?
Network track → Main track → long-running task → LCP marker → interaction → rendering work
A trace shows browser work over time. It does not automatically prove which event is the root cause.
When to Use a Performance Trace Instead of the Network Waterfall
The network waterfall is usually better for request timing, transfer, discovery and initiators.
A Performance Trace becomes especially useful when:
Do not use a trace as the first tool for every performance problem.
If the browser is still waiting for a critical request, network evidence may be more direct. If the request is already complete but the user-visible result is late, the trace becomes much more valuable.
Record the Right Scenario Before You Analyze Anything
A trace is only useful if it captures the symptom you care about.
Before recording:
- define the exact scenario;
- use a representative URL or interaction;
- decide whether you are testing cold or warm conditions;
- note the device and network profile;
- avoid unrelated clicks, scrolling or background activity;
- repeat the scenario if performance is variable.
Do not start with the trace. Start with the question.
Use a controlled performance baseline so before/after comparisons remain meaningful.
Page-Load Traces vs Interaction Traces
Use for startup and rendering symptoms
Useful for LCP, startup scripting, style/layout work and render delay during initial load.
Use for runtime responsiveness
Useful for slow clicks, menus, input responsiveness and interaction processing.
Do not mix the two scenarios unless the problem genuinely spans both.
A clean interaction trace can make it easier to isolate a slow click than a long recording containing navigation, scrolling, animations and unrelated input.
How to Orient Yourself in the Performance Panel
You do not need to understand every track before you can diagnose useful performance patterns.
For most investigations, focus on:
- Overview — where activity clusters in time;
- Network — whether requests are still active;
- Main — main-thread tasks and browser work;
- Timings — important markers, including user timings where present;
- Interactions — user interaction timing and responsiveness;
- performance markers — including LCP and FCP where relevant;
- Summary — details for the selected event or marker.
Chrome’s Performance panel also surfaces Insights, but the principle in this guide remains the same: use the trace to connect a user symptom to observable browser work.
Start With the Main Thread
The main thread performs much of the work needed to run and display a page.
That can include:
- JavaScript execution;
- event handlers;
- style calculation;
- layout;
- paint preparation;
- other rendering-related work.
If the main thread is continuously busy, the browser has fewer opportunities to respond to input or progress rendering work.
Critical resources complete → Main thread continues scripting / style / layout → Paint or interaction remains delayed
A busy main thread is an observation, not a diagnosis. The next task is to identify which work dominates the relevant time window and whether it actually blocks the user-visible outcome.
What Tasks and Long Tasks Mean
Main-thread work is represented as tasks and nested events in the trace.
You do not need to memorize the entire event taxonomy.
The practical objective is to locate expensive regions and inspect what is happening inside them.
Long-running tasks are useful warning signs because they indicate the main thread remained occupied for a meaningful period without yielding.
Chrome DevTools marks long-running tasks in the Performance panel to make them easier to investigate.
But a long task is not automatically the root cause of the metric you care about.
See long tasks for the dedicated analysis.
How to Read JavaScript Execution in a Trace
JavaScript cost is not just download size.
Runtime cost can include:
- parsing;
- compilation;
- execution;
- callbacks;
- event handlers;
- framework work;
- application logic.
When scripting dominates a relevant time window:
- zoom into that time window;
- select the expensive task;
- inspect its nested activity;
- identify source scripts or functions where available;
- use Bottom-Up or Call Tree when the task is too complex to interpret directly.
Do not conclude that “all JavaScript is the problem.” Attribute cost to the specific work that overlaps the symptom.
Style Recalculation, Layout and Rendering Work
JavaScript is not the only source of main-thread cost.
Style recalculation
After DOM or style changes, the browser may need to recalculate which styles apply to elements.
Repeated or expensive recalculation can add browser work.
This does not mean complex CSS selectors are automatically the root cause. The trace tells you that style work happened; additional evidence is needed to understand why.
Layout
Layout determines element geometry and position.
Repeated or expensive layout can extend the time before the browser can present the next frame or important content.
Paint and rendering
Even after resources are downloaded, the browser may still need to process style, layout and paint-related work before pixels appear.
Resource complete does not mean element visible.
If an LCP resource is already available but paint happens much later, see LCP resource loads before the paint.
How to Investigate LCP With a Performance Trace
For LCP diagnosis, start with the metric marker and work backward through the relevant time window.
Chrome’s Performance trace can show important performance markers including LCP.
Ask:
- When did the LCP event occur?
- When did the LCP resource finish loading?
- Was the main thread busy between resource completion and LCP?
- Was scripting, style, layout or rendering work present in that gap?
- Does the suspected work repeat across comparable traces?
Observation: LCP resource finishes early, LCP marker occurs later.
Hypothesis: browser work may be delaying render opportunity.
Next evidence: inspect the Main track in the gap.
For the broader decomposition, see diagnose slow LCP.
How to Investigate Slow Interactions
For a slow interaction, record the specific action rather than scanning a full page-load trace.
The Interactions track can help you inspect:
- input delay;
- processing time;
- presentation delay;
- the main-thread work occurring around the interaction.
If input arrives while the main thread is already busy, the interaction may have to wait before its handler can run.
If event processing itself is expensive, the trace can reveal that work.
If rendering after processing is delayed, the presentation phase may deserve investigation.
For the metric itself, see Interaction to Next Paint. For the dedicated relationship between long tasks and responsiveness, see long tasks and INP.
Third-Party Scripts and Main-Thread Cost
A trace can reveal CPU activity associated with external scripts such as:
- analytics;
- advertising;
- tag managers;
- consent systems;
- chat widgets;
- heatmaps;
- embedded tools.
That evidence is useful, but it does not mean the script should automatically be removed.
Ask:
CPU cost and business necessity are separate questions. Performance engineering needs both.
First-Party vs Third-Party Cost
When possible, classify expensive work into:
- first-party application code;
- third-party code;
- browser rendering work.
This helps avoid vague conclusions such as “JavaScript is heavy.”
A better finding identifies:
Use Bottom-Up to Find Expensive Work
Bottom-Up is useful when the question is:
It is cost-centered.
Chrome DevTools distinguishes:
- Self Time — time spent directly in an activity;
- Total Time — time spent in that activity including child activity.
Select a focused time range first. Then use Bottom-Up to identify expensive activity inside that range.
Do not run Bottom-Up against an unfocused multi-second trace and assume the largest total is the user-visible bottleneck.
Use Call Tree to Understand Execution Paths
Call Tree answers a different question:
It is hierarchy-centered rather than purely cost-centered.
| View | Best question |
|---|---|
| Bottom-Up | Which activities consumed the most self or total time? |
| Call Tree | Which execution hierarchy or path led to the work? |
Both can become noisy without a focused time window.
Network Bottleneck or CPU Bottleneck?
Browser is still waiting on important requests
Use request timing, transfer, discovery and initiator evidence.
Requests are done but the browser remains busy
Inspect scripting, style, layout, rendering and interaction processing.
Both can exist at the same time.
The practical goal is to determine which path dominates the specific user-visible delay.
See network vs CPU bottleneck.
Common Trace Patterns and What They Suggest
| Trace pattern | What it suggests | What it does NOT prove | Next step |
|---|---|---|---|
| Long scripting task before LCP | Main thread is busy near the LCP window | That all JavaScript is problematic or that this task definitely caused LCP | Inspect source, overlap and blocking relationship |
| Heavy style/layout work | Rendering-related CPU cost exists | That CSS alone is the root cause | Inspect DOM/style changes and repeated behavior |
| Third-party task consumes significant CPU time | External script contributes main-thread work | That it should be removed | Evaluate timing, scope and business requirement |
| Interaction begins while another task is running | Input may wait for the main thread | That the task alone explains field INP | Inspect interaction timing and repeat behavior |
| Resources complete, main thread remains busy | Network may no longer be the dominant bottleneck | That JavaScript specifically is responsible | Inspect work type in the relevant window |
Pattern 1 — Network complete, main thread still busy
This is the classic reason to move from a waterfall to a trace.
Potential work includes scripting, style, layout and rendering.
Do not jump directly to “reduce JavaScript.” Identify the dominant work first.
Pattern 2 — Long JavaScript task before LCP
A long scripting task that overlaps the time before LCP is useful evidence.
But temporal proximity alone does not prove the task delayed LCP.
Inspect whether the task prevents the browser from reaching the rendering work required for the LCP element.
Pattern 3 — Interaction waits behind existing work
If input occurs while the main thread is occupied, the browser may not be able to begin processing the interaction immediately.
This can contribute to input delay.
Pattern 4 — Repeated style/layout bursts
Repeated style or layout activity can point toward DOM mutations, rendering logic or layout-heavy interactions.
Additional evidence is required before naming a root cause.
Pattern 5 — Third-party CPU work
If an external script appears inside expensive tasks, investigate whether its timing and scope are necessary for that page state.
Performance cost alone does not resolve the business decision.
Tool / View → Best For → Limitation
| Tool / View | Best for | Limitation |
|---|---|---|
| Network Waterfall | Request timing, response, transfer, discovery, initiator | Does not fully show CPU execution or rendering cost |
| Performance Trace | Main-thread, scripting, style, layout, rendering, interactions | Does not expose full server/application internals |
| Bottom-Up | Finding expensive activity in a selected time range | Needs context to connect cost with user impact |
| Call Tree | Understanding execution hierarchy and paths | Can be noisy without a focused window |
| Summary | Inspecting details for a selected event or marker | Only explains the selected item; broader causation still needs context |
Correlation Is Not Root Cause
This is one of the most important trace-analysis rules.
Observation: a long task occurs before LCP.
Hypothesis: the task may delay a render opportunity.
Confirmation: reduce or isolate the task, then compare the trace and LCP under equivalent conditions.
Before claiming causation, look for:
- timing overlap;
- a plausible dependency or blocking relationship;
- repeatable behavior;
- before/after evidence;
- contradicting evidence.
A trace is excellent for forming hypotheses. Verification turns a hypothesis into a stronger engineering conclusion.
A Practical Performance Trace Investigation Workflow
Observe the user-visible symptom
Define whether the problem is page load, LCP, a click, input or a visual stall.
Locate the relevant time window
Start from the LCP marker, interaction or visible delay rather than scanning the entire trace.
Inspect the Main track
Determine whether the main thread is busy during that window.
Identify the dominant work type
Separate scripting, style, layout, rendering and third-party work.
Trace the work to a source
Use event details, script attribution, Bottom-Up or Call Tree where useful.
Form a hypothesis
Describe how the work may block the user-visible outcome.
Confirm the relationship
Use repeated traces, dependency evidence or controlled isolation.
Fix the responsible source
Apply the smallest targeted change supported by evidence.
Verify
Record the same scenario again and compare metrics, tasks and regressions.
Symptom → Time Window → Main Thread → Expensive Work → Source → Hypothesis → Confirmation → Verify
A Practical Performance Trace Decision Tree
Network active? → Main thread busy? → Work type? → Source? → Confirm
IS THE PAGE SLOW BECAUSE NETWORK IS STILL ACTIVE? │ ├─ YES │ └─ Network Waterfall investigation │ └─ NO ↓ IS THE MAIN THREAD BUSY? │ ├─ YES │ ↓ │ WHAT TYPE OF WORK DOMINATES? │ ├─ SCRIPTING │ │ └─ Inspect JavaScript source / call path │ ├─ STYLE / LAYOUT │ │ └─ Inspect rendering path and DOM/style changes │ ├─ THIRD-PARTY │ │ └─ Inspect dependency, scope and business need │ └─ MIXED │ └─ Isolate by symptom time window │ └─ NO ↓ CHECK RENDERING / COMPOSITOR / APPLICATION-SPECIFIC STATE
Common Performance Trace Analysis Mistakes
Recording without a clear scenario
A trace without a question produces noise.
Scanning the entire trace
Start from the symptom window instead.
Seeing lots of JavaScript and blaming JavaScript
Attribute cost to specific work before concluding.
Looking at network and ignoring the Main track
Network completion does not mean browser work is complete.
Confusing correlation with causation
Temporal proximity is not enough.
Looking only at total CPU time
User impact depends on timing, blocking and scenario.
Not separating first- and third-party cost
Ownership matters for remediation.
Ignoring LCP or interaction markers
Metrics give you a time window to investigate.
Recording only one trace
Variable behavior needs repeated evidence.
Ignoring DevTools or extension noise
Control the environment when repeatability matters.
Changing many things at once
Attribution becomes weak.
Not saving the before trace
You lose evidence needed for comparison.
Not verifying after the change
A code change is not proof of improvement.
Using a trace to diagnose server internals
Server root cause needs server/application evidence.
Ignoring the waterfall when network timing matters
Trace and waterfall answer different questions.
What a Performance Trace Cannot Tell You
A trace does not automatically provide full evidence for:
Those questions may require:
- server logs or APM;
- application profiling;
- database evidence;
- HTTP/cache evidence;
- CrUX or RUM;
- business context.
Use the trace as one evidence layer in the broader root-cause investigation framework.
How to Verify a Fix With a Second Trace
After a change, record the same scenario again.
Keep comparable:
- URL or interaction;
- device profile;
- network profile;
- cache state where relevant;
- page state;
- measurement method.
Then compare:
- task duration;
- long-running task behavior;
- scripting/style/layout distribution;
- LCP or interaction timing;
- new rendering or network regressions;
- whether the suspected source actually changed.
See verify a performance change.
When a Deeper Performance Investigation Is Needed
A deeper investigation is useful when:
A Performance Trace is most valuable when the network does not fully explain why the page is slow. It can reveal where the browser spends time on scripting, rendering and interaction processing, but those observations still need to be connected to the responsible dependency and verified before production changes are made.
The network looks fast, but the browser is still slow?
A structured browser performance investigation can connect Performance Trace evidence with network timing, source attribution and application behavior to identify the work that actually blocks rendering or responsiveness before production changes are made.
WebPerfLab — Measure → Trace → Diagnose → Fix → Verify
Final Takeaway
A Performance Trace is useful because it shows what the browser was doing while the user was waiting.
Start with the symptom.
Locate the relevant time window.
Identify the expensive work.
Trace it to the source.
Then test whether changing that source actually improves the metric or interaction.
Locate→
Trace→
Hypothesize→
Confirm→
Fix→
Verify
Do not optimize what looks busy. Diagnose what blocked the user-visible outcome.