Performance Bug Reports: Turning 'It Feels Slow' Into a Number

Written By  Crosscheck Team

Content Team

August 2, 2026 9 minutes

Performance Bug Reports: Turning 'It Feels Slow' Into a Number

Performance bug reports: turning "it feels slow" into a number

A tester files a ticket: "Orders page feels slow." A developer opens the page on a fast laptop with a warm cache and a test account holding four orders. It loads in under a second, so they close the ticket as "cannot reproduce."

Nobody lied. The tester had 4,000 orders and hotel wifi. The developer had four orders and fibre. The fix is not more words. It is numbers.

Short version

  • "Slow" is an opinion. A number is a bug.
  • Measure with Chrome DevTools, and throttle so your result is repeatable.
  • Report the median of at least 5 runs, never a single run.
  • Always state device, network, cache state, and how much data was in the account.
  • Name the exact slow request and its timing.
  • Agree a performance budget in advance so the report says "we are over budget."

Why "it feels slow" gets closed

A developer needs three things before they can fix a speed problem: something to reproduce, something to measure, and something to compare against. "It feels slow" gives none of them, and it can never be proven fixed.

A number gives all three. "The orders list takes 8.4 seconds to show the first row" can be reproduced, measured, and compared after the fix.


Open the tools before you complain

Everything below uses Chrome DevTools. Open it with F12, or Cmd+Option+I on a Mac. Two panels matter.

The Network panel shows every file and API call the page requested, how long each took, and how big each was.

The Performance panel records what the browser was doing over time: downloading, running JavaScript, drawing pixels. Use it when the network looks fine but the page stalls.

Throttle, or your numbers are useless

Throttling means telling the browser to pretend it is on a slower connection or device. Without it, your result depends on your office wifi that afternoon, so nobody can repeat it.

In the Network panel, set the throttle dropdown to Fast 3G. In the Performance panel settings, set CPU to 4x slowdown. Together they roughly match a mid-range Android phone on mobile data, which is what many of your users have.

Always state the throttle setting in the ticket.


Web Vitals: the three numbers to learn

Web Vitals are a small set of standard speed measurements defined by Google. Standard matters here, because it means your number means the same thing to everyone on the team.

Three of them cover almost every performance bug you will file.

LCP (Largest Contentful Paint) — how long until the biggest thing on the screen appears. Usually the hero image, the headline, or the first row of a table. This is the honest answer to "when did the page look loaded?"

INP (Interaction to Next Paint) — how long the page takes to visibly respond after you click, tap, or type. If you click Save and the button sits there dead for half a second, that is INP.

CLS (Cumulative Layout Shift) — how much the content jumps around while loading. A score, not a time. You have felt this when an ad loads late and you tap the wrong link.

Here are the targets most teams use:

MeasurementGoodNeeds workPoor
LCPunder 2.5s2.5s to 4.0sover 4.0s
INPunder 200ms200ms to 500msover 500ms
CLSunder 0.10.1 to 0.25over 0.25

You can read all three live. Record a page load in the Performance panel, or install the Web Vitals Chrome extension, which shows the three values in the toolbar as you browse.


Read the waterfall and name the slow request

The Network panel draws a waterfall: one horizontal bar per request on a timeline. Long bars are slow requests. A bar that starts late was waiting for something before it.

Sort by the Time column, click the slowest row, and open the Timing tab. The stage that matters most is TTFB (Time To First Byte) — how long the server took to start answering. High TTFB means the problem is on the server, not in the browser.

Write it down like this:

GET https://api.staging.example.com/v1/orders?page=1 took 4.2s. Response was 1.8 MB. TTFB was 3.1s.

That line tells a developer almost everything. TTFB of 3.1s out of 4.2s means the server spent three seconds building the response, probably a slow database query. The 1.8 MB size says the endpoint also returns far more data than one page of results needs.

Compare that to "the orders API is slow." One of these gets opened first.


From vague complaint to a real line in a ticket

Use this table as a translation guide.

The vague complaintThe measurement to takeThe line to put in the ticket
"The page takes forever to load"LCP in the Performance panel"LCP is 7.8s on Fast 3G, 4x CPU. Target is 2.5s."
"It hangs when I click Save"INP, or record the click in the Performance panel"Clicking Save blocks the main thread for 940ms before any visual change."
"The page jumps while loading"CLS"CLS is 0.34. The banner pushes the form down 180px at 1.2s."
"The list is slow with lots of data"Network panel, slowest request"GET /v1/orders?page=1 took 4.2s with 4,000 orders in the account, 0.3s with 12."
"It's slow the first time only"Compare cold and warm cache runs"Cold cache: 6.1s. Warm cache: 1.4s. 2.2 MB of JS is uncached."
"Scrolling is choppy"Performance panel recording, frame rate"Scrolling the orders table drops to 22fps. A scroll handler runs 180ms per frame."

Run it five times and report the median

One measurement is noise. A background download, a cold server, or a browser extension waking up can double a single result. Do this instead:

  1. Open the page in a new incognito window, so extensions do not interfere.
  2. Set throttling to Fast 3G and 4x CPU slowdown.
  3. Load the page and write down the number.
  4. Repeat until you have 5 runs.
  5. Sort the 5 numbers and take the middle one. That is your median.

For example: 6.9, 7.4, 7.8, 8.1, 12.6. The median is 7.8s. Report that, and mention the range. The 12.6s outlier is worth a note, not a headline.


The four facts that make it reproducible

Every performance number needs these four next to it, or the developer cannot repeat your test.

  1. Device and browser. "MacBook Air M2, Chrome 141" or "Pixel 6a, Chrome Android."
  2. Network and CPU throttle. "Fast 3G, 4x CPU slowdown" or "no throttling, office wifi."
  3. Cache state. Cold cache means the browser has nothing saved and must download everything. Warm cache means it reuses files from an earlier visit. First visits are cold. Say which you tested.
  4. Data volume. How much data was in the account. "[email protected], 4,000 orders, 18 saved filters." This is the most common reason a developer cannot reproduce a slow page.

Crosscheck records the console, the network requests, and the browser and device details at the moment you file the report, so that is several of these you do not type by hand.


Before and after numbers prove the fix

Measure again after the fix lands, using the exact same steps, and put both numbers in the ticket.

Before: median LCP 7.8s (5 runs, Fast 3G, 4x CPU, cold cache, 4,000 orders). After: median LCP 2.1s (same steps, same account). GET /v1/orders?page=1 went from 4.2s / 1.8 MB to 0.4s / 96 KB.

Now the fix is proven. Six months later, when someone asks whether the orders page got faster, the answer is in the ticket.


Agree a budget before you file

A performance budget is a number the team agrees on in advance. For example: the orders page must reach LCP under 2.5s on Fast 3G with a 1,000-order account.

Without a budget, your report is an opinion and someone can reply "seems fine to me." With one, it is a failed check:

Bad: Orders page feels slower than it used to.

Good: Orders page LCP is 4.6s. Budget is 2.5s. We are 2.1s over.

Keep it short. Three or four numbers on your most important pages is plenty. Write them somewhere the whole team can see, and add the budget line to your definition of done.


A template you can copy

Title: Orders list takes 7.8s to render first row with 4,000 orders

Summary
LCP on /orders is 7.8s. Budget is 2.5s. Over budget by 5.3s.

Environment
- URL: https://staging.example.com/orders
- Account: [email protected] (4,000 orders, 18 saved filters)
- Device: MacBook Air M2, Chrome 141
- Throttle: Fast 3G, 4x CPU slowdown
- Cache: cold (incognito, first load)

Measurements (5 runs, median reported)
- LCP: 7.8s (range 6.9s - 12.6s)
- INP on the Filter button: 610ms
- CLS: 0.04 (within budget)

Slowest request
GET https://api.staging.example.com/v1/orders?page=1
- Total: 4.2s
- TTFB: 3.1s
- Response size: 1.8 MB

Comparison
Same steps with a 12-order account: LCP 1.3s, request 0.3s / 41 KB.

Attached
DevTools performance recording, HAR export of the network log

The comparison line is the most valuable part. It shows the problem scales with data volume, which points straight at the query or the missing pagination.


Frequently asked questions

Do I need to be a developer to file a performance bug report? No. Every step here is reading numbers off a screen, not writing code. Open DevTools, set the throttle, load the page, and copy the values.

What if the page is slow but every request is fast? Then the delay is in the browser, not the network. Record the load in the Performance panel and look for long yellow blocks, which are JavaScript. Attach the recording.

Should I test on staging or production? Test on staging first, because the team can change it safely. If the problem only appears on production, say so — that usually points to a data volume or configuration difference.

How slow is slow enough to file? If it misses your agreed budget, file it. Without a budget, use the Web Vitals targets: LCP over 2.5s, INP over 200ms, or CLS over 0.1 on a page people use every day.

My number changes every time I run it. What do I report? Report the median of 5 runs and include the range. If the range is very wide, such as 2s to 12s, that instability is itself a bug worth reporting.

Related Articles

Contact us
to find out how this model can streamline your business!

Trusted by thousands ofengineering teams worldwide.

Add to Chrome
200+ reviews · 100k+ users
Crosscheck browser extension capture controls

Join the Crosscheck Community

Stay in the loop with Crosscheck's newest features and insights.