When I compared CometWeb with three competing pages, one of them had an LCP of 13.3 seconds and a Lighthouse score of 71. CometWeb showed 5.8 seconds for LCP but scored 69 overall. Looking only at the scores would have hidden a substantial difference in how quickly the main content appeared.
A useful benchmark compares equivalent page types, test conditions and individual metrics. This guide works through four sites and 20 Lighthouse runs, then shows how to record the method so the comparison can be repeated.
What a website benchmark is
A website benchmark is a measurement of your site and a fixed set of comparable pages with the same method, under the same conditions, with a record of how you did it.
A useful benchmark answers three questions:
- where you're behind;
- by how much;
- whether the gap matters for the pages that earn you money.
Step 1: Decide what the benchmark is for
Write the question down first, because a benchmark with no decision at the end ends up as a report nobody uses, or even reads.
- "Why do competitors outrank us on our main category queries?" Compare the pages that rank for those queries.
- "Is our checkout slower than the market?" Compare the equivalent step in each checkout, on the device most of your buyers use.
- "Did the redesign make us worse?" Compare yourself with your previous version first, using the same method, and bring in other sites later.
My question was narrow on purpose, because I wanted to know whether cometweb.io/website-audit is technically behind the pages that rank for "website audit" queries. And if so, where?
Step 2: Pick competitors for the benchmark from the search results
Your rivals in the sales deck and in search are often different companies. For an SEO or performance benchmark, take three to five domains that keep showing up in the top ten for your queries.
Adding more sites increases the work involved. With too small a sample, it is also easy to mistake one unusual competitor for the market. Keep the set fixed until the retest, because if you swap a competitor between runs, your trends stop meaning anything.
How I picked three pages
I pulled two queries, "free website audit tool" and "website audit", from a search API (United States, ten results).
| Page | "free website audit tool" | "website audit" | Decision |
|---|---|---|---|
| seoptimer.com | 2 | 2 | Chosen; could not be measured |
| thehoth.com/seo-audit-tool | 3 | 5 | Measured |
| seositecheckup.com | 5 | 7 | Measured |
| rankmath.com/tools/seo-analyzer | 6 | 10 | Reserve; measured |
| cometweb.io/website-audit | outside top ten | outside top ten | Our page |
A search API result is a snapshot from one place at one moment, so I only used it to choose pages.
Name a reserve before you see the first numbers
My first choice, SEOptimer, wouldn't load in the test window. Lighthouse showed a blank page (NO_FCP) and two single requests returned HTTP 525, so the reserve, Rank Math, took its place.
Name your reserve before you measure, because if you choose a replacement after seeing the first numbers, it's easy to pick the comparison that flatters you.
Step 3: Compare pages with the same template and purpose
Put homepage against homepage and product page against product page.
| Your page | Compare with | Why |
|---|---|---|
| Homepage | Competitors' homepages | Same role: brand entry and navigation |
| Category or listing page | The ranking category page for the same query | Same intent and similar content density |
| Product or service page | A comparable product or service page | Same template type and conversion role |
| Article | The article ranking for the same query | Same search intent |
| Checkout or sign-up step | The equivalent step | Same task, often the most valuable |
One page per template is a sample of your site, so label it that way. Add more when your template varies a lot, like long and short product pages.
In my case the ranking URLs set the comparison, two audit-tool pages and a homepage that's a tool's entry point. So my equivalent is the service page built for that intent.
Step 4: Compare field data, and use lab data to explain the gap
Performance numbers come in two kinds, and mixing them is the most common mistake you can make here.
Field data, per the CrUX API documentation, is published by the Chrome UX Report (CrUX) as a 28-day rolling average with the 75th percentile as the headline value. Under the CrUX methodology, only publicly discoverable pages with enough visitors get data, so your smaller competitors may have none at all.
Lab data describes a different load from the one your users had (web.dev). I dig into this in lab data vs CrUX field data.
Compare Core Web Vitals on field p75 values, separately for mobile and desktop. According to web.dev, the thresholds are LCP up to 2.5 seconds, INP up to 200 milliseconds and CLS, how much the layout shifts while loading, up to 0.1.
INP, how fast a page responds to interaction, became a stable Core Web Vital in 2024 and replaced FID. Lighthouse can't measure it, because nobody clicks during a lab load, so its lab proxy is Total Blocking Time (TBT), the total time the main thread is blocked.
| Situation | What to compare | What not to do |
|---|---|---|
| Both sites have CrUX data | Field p75 per device class | Rank on the Lighthouse score |
| A competitor has no CrUX data | Lab metrics under identical settings, labelled as lab | Treat missing field data as zero or as "good" |
| You need to explain a gap | Lab traces: resources, blocking time, largest element | Present a single lab run as the user experience |
My example has lab data only, because the CrUX API needs a Google Cloud key I didn't have for this run, so my field data cell says "not measured".
Step 5: Set up lab runs so you can compare them
According to the Lighthouse scoring documentation, most variability in the score and metrics comes from changing conditions, not Lighthouse itself: A/B tests, network routing, a different machine, browser extensions. So it suggests you treat performance as a distribution.
The project's variability guide adds that the median of five runs is about twice as stable as one run. It also warns that you shouldn't collect several reports at once on one machine.
In practice:
- Run every site from the same location, device profile and network throttling.
- Run each page several times, interleaved across sites. Compare medians, and keep your best and worst runs for the min–max column.
- Test all sites in the same time window, since third-party scripts and ads change during the day.
- Compare the metrics that explain the gap, which are LCP, TBT and CLS, because the composite score blends them.
How I measured this
| Setting | Value |
|---|---|
| Tool | Lighthouse 13.5.0 (score weights as in its default configuration), Chrome for Testing 153 from Playwright, headless, fresh profile per run |
| Device and network | Default mobile preset: Moto G Power emulation, simulated throttling with 150 ms RTT, about 1.6 Mbps and 4× CPU slowdown 6 |
| Runs | 5 per page, rounds interleaved and rotated, 8-second pause after each |
| Window | 24 September 2026, 07:11–07:17 UTC |
| Reported | Median, with minimum and maximum |
I measured four pages, my /website-audit and the three ranking pages from step 2, five runs each, 20 in total. Every number is a lab value from one machine, one network location and six minutes on one morning.
I measured one page per site. I didn't judge what these audit tools find or how useful they are, and I don't report rankings.
One weak spot: the runs were sequential, but other work ran on the same machine. The methodology lists every limitation, including headless Chromium and the first run I aborted.
Step 6: Compare median LCP across five runs
Median lab LCP ran from 2.2 to 13.6 s, and mine came second, 3.6 s behind Rank Math (5.8 s against 2.2 s).
My page also has the slowest First Contentful Paint (FCP, when the first content appears) of the four (3.8 s), though the next one is close behind at 3.7 s. I use that difference when reviewing the priorities in step 9.
A score of 71 at 13.3 s LCP, 69 at 5.8 s
The HOTH page took a median 13.3 s to load and scored 71, while mine scored 69 at 5.8 s. So that page is slightly ahead of me on the score, even though it's 7.4 seconds behind on LCP.
Why the gap? The weights in the Lighthouse scoring documentation explain it.
The HOTH's page paints first content at 1.7 s with almost no layout shift, and that roughly offsets what it loses on a late LCP. The two pages have different problems, and the score hides both.
LCP moved by up to 886 ms, so use medians
My own page moved by 886 ms between its fastest and slowest LCP run, from 5,475 to 6,362 ms, while the Rank Math page moved by only 4 ms. The SEO Site Checkup page scored 59, 60, 60, 69 and 60. In one run first content painted at 1.4 s, against about 3.7 s in the other runs, and the score jumped nine points.
One run would've given you 60 or 69, depending on luck. The median of five says 60, and the spread tells you how far you can trust it.
Page weight differed by a factor of ten
Page weight on a cold load ran from 193 kB to 2,024 kB. According to Lighthouse, on The HOTH and SEO Site Checkup third-party origins sent 72% and 84% of the bytes, on mine about 2%, and on Rank Math's zero. "Third party" means origins Lighthouse doesn't attribute to the page's owner, so a company's own tool embedded from another domain counts too.
Step 7: Benchmark SEO, accessibility and security too
Compare each area with checks that mean the same thing on every site.
| Area | Comparable checks | Watch out for |
|---|---|---|
| Performance | Field p75 LCP, INP, CLS; lab LCP and Total Blocking Time; transferred bytes | Mixing field and lab values in one column |
| Technical SEO | Indexability of the compared page, canonical, title and description, structured data, internal links to it | Counting issues without weighing whether they affect the ranking page |
| Accessibility | Automated issues on the same templates; keyboard path through the key task | Treating a lower automated issue count as WCAG conformance |
| Security | HTTPS and TLS configuration, security headers, mixed content | Scoring a missing header the same as an exploitable flaw |
| Page weight and carbon | Transferred bytes on first view; model-based CO₂e with the same method | Comparing estimates made with different models or versions |
On technical SEO, all four pages returned 200 over HTTPS and were indexable and self-canonical. They all had JSON-LD structured data too, with titles running from 43 to 71 characters.
Two pages had two <h1> elements in server HTML, and one failed Lighthouse's crawlable-anchors audit. On the basics that decide whether a page can rank, all four were fine.
On accessibility I ran automated audits only, and Lighthouse scored my page 100 and the others 94, 85 and 95, with colour contrast failing on three pages. Each audit is pass or fail (Lighthouse accessibility scoring docs), and automatic detection finds only a subset of issues (default configuration). WCAG conformance needs a manual pass with a keyboard and a screen reader, and I skipped it, so my 100 only means the automated audits found nothing. My accessibility audit guide covers a full review.
Security headers: record each header's value
| Header (one response, one page) | CometWeb | The HOTH | SEO Site Checkup | Rank Math |
|---|---|---|---|---|
| Strict-Transport-Security | max-age=15552000 | max-age=31536000 | absent | max-age=31536000; includeSubDomains |
| Content-Security-Policy | upgrade-insecure-requests only | frame-ancestors 'self' | absent | absent |
| X-Content-Type-Options | nosniff | absent | absent | absent |
| X-Frame-Options | SAMEORIGIN | absent | absent | absent |
| Referrer-Policy | strict-origin-when-cross-origin | absent | absent | absent |
| Permissions-Policy | present | absent | absent | absent |
Counting headers, my page "wins" six to two, but that count flatters me. My CSP (Content-Security-Policy, the list of allowed content sources) has only upgrade-insecure-requests. According to MDN, that directive only upgrades HTTP URLs to HTTPS, and which scripts may run stays unrestricted.
A missing header shows a configuration difference, and you'd have to prove an exploitable flaw separately. Record values instead of ticks, and check your own policy with our CSP checker.
Step 8: Record the benchmark so you can repeat it
Keep one row per page and measurement, with these fields:
- date and time window;
- site and page, with the template name;
- data type: field (such as CrUX over 28 days on
PHONE) or lab (such as Lighthouse on a mobile profile); - tool, with its version and throttling settings;
- number of runs and which value you report;
- the metrics;
- the other areas: indexability, canonical target, automated accessibility issues, security headers;
- a not measured field, such as "no CrUX data for this origin", that's never left blank.
The last field matters most, because "not measured" and "measured as good" are different findings, and a blank cell turns one into the other.
The filled record from my example
I used the settings from "How I measured this", so it's lab data only and the median of five runs.
| Field | CometWeb | The HOTH | SEO Site Checkup | Rank Math |
|---|---|---|---|---|
| Page | /website-audit | /seo-audit-tool/ | homepage | /tools/seo-analyzer/ |
| LCP (min–max) | 5.8 s (5.5–6.4) | 13.3 s (12.9–13.3) | 13.6 s (13.4–13.8) | 2.2 s (2.2–2.2) |
| FCP | 3.8 s | 1.7 s | 3.7 s | 1.1 s |
| TBT / CLS | 0 ms / 0.000 | 67 ms / 0.003 | 175 ms / 0.021 | 0 ms / 0.000 |
| Performance score (min–max) | 69 (67–72) | 71 (71–72) | 60 (59–69) | 99 (99–99) |
| Transferred / third party | 582 kB / 10 kB | 2,024 kB / 1,454 kB | 1,736 kB / 1,467 kB | 193 kB / 0 kB |
| Requests | 64 | 66 | 94 | 23 |
| Indexable, canonical | yes, self | yes, self | yes, self | yes, self |
| Automated accessibility | 100, none failing | 94, 2 failing | 85, 4 failing | 95, 2 failing |
| Security headers present (of 6) | 6 (CSP weak) | 2 | 0 | 1 |
| Not measured | Field data, INP, keyboard path, manual WCAG, TLS, other templates | same | same | same |
The full record, with every header value and structured-data type, is in benchmark-record.csv, so copy its columns into yours.
Step 9: Turn the benchmark gaps into a short list, then retest
Rank each gap by what the page is worth and how far behind you are. A two-second LCP gap on a category page that ranks for your main query beats twenty minor warnings on a legal page.
What the benchmark said about my page
The benchmark ruled one explanation out, because two pages with a median lab LCP above 13 seconds are in the top ten for both queries. My page loaded in 5.8 s and made neither list, so lab speed doesn't explain my absence. That fits Google's Understanding page experience: Search tries to show the most relevant content even when the page experience is sub-par.
One honest caveat: ruling an explanation out doesn't prove another one in, so relevance and authority need their own analysis. I still got a technical short list out of it, and the fastest page shows you can hit a 2.2 s lab LCP here.
- First paint. My FCP of 3.8 s is the slowest of the four, and a diagnostic run found the LCP element is the word "CometWeb" in the logo. The server answered in 68 ms, so the work is in the render path. Lighthouse estimated a 700 ms saving from seven render-blocking stylesheets, but I'll retest after the layout change first and only then fix the stylesheets.
- Content Security Policy. I'll swap a header that only upgrades URLs for a policy that restricts sources, and test it before enforcing it.
- The rest stays, because TBT, CLS, third-party weight and the indexing basics are fine.
Side note: I only tested that 700 ms on the homepage, where the LCP element is the same logo, and deferring CSS there the same day gained about 0.1 s. More came from cutting JavaScript that the layout every page shares loaded before first render. My benchmark numbers predate that change, and the retest will show what /website-audit gained.
For practical examples of investigating LCP and blocking time, see how to speed up a website: 7 fixes with measurements.
Retest your benchmark with the same method
After you ship a fix, rerun the same pages with the same method, device class and number of runs. My retest reuses the script, the four URLs and the reserve rule unchanged.
Competitor benchmarking in CometWeb Insight
You can do all of this by hand, with Lighthouse and a spreadsheet. The Competitors module in CometWeb Insight, our website audit app, runs this comparison for your domain and up to three rivals:
- scans every domain with the same modules: performance, SEO, accessibility, security and ecology;
- shows where you lead and where you have a technical gap;
- tracks the distance over time, because each new scan adds a point to the trend.
Insight measures the pages it scans, so it doesn't estimate your competitors' traffic or revenue. You get the same checks on every domain, the hardest part to keep up by hand.
Three takeaways
- The composite score blends metrics. The HOTH page took 13.3 s to load and scored 71, while mine scored 69 at 5.8 s, so compare LCP, TBT and CLS separately.
- Set the method before you measure, because a reserve you choose after seeing the numbers tends to flatter you. A median of five runs protects you from the run that drifts, by 886 ms in my case.
- "Not measured" is a finding of its own. A blank cell turns it into "measured as good", so write down what you didn't measure.
I lost on LCP, 5.8 s to 2.2 s, and came away with two fixes. This week, pick three pages from the top ten for your main query, name a reserve and run each page five times. If you'd rather have the comparison run itself, create a CometWeb Insight account.
Frequently asked questions
How often should I benchmark a website?
Before and after significant changes, such as a redesign, a migration or a new template, and on a regular cadence that matches how often you ship. Because CrUX uses a 28-day rolling window, a monthly comparison of field data is the shortest interval that shows a full window after a change.
Can I benchmark a website in PageSpeed Insights?
Yes, as long as you measure every page the same way. PageSpeed Insights shows CrUX field data from the previous 28 days, and when a URL has too little data it falls back to the whole origin or shows none at all. The lab part is a Lighthouse run in a simulated environment, so the rules from step 5 still apply: several runs per page, the median and the same time window. I ran Lighthouse locally because the anonymous PageSpeed Insights API answered "quota exceeded".
How do I compare my website's carbon footprint with competitors?
Estimate every page with the same model and the same model version. Start from the bytes transferred on first view, which you already have from Lighthouse. Keep estimates from different models or versions out of the same comparison. Our website carbon footprint guide explains why the version has to match and includes an SWDM v4 calculator.
How do I compare accessibility with competitors when automated tests only catch some issues?
Record two things separately: automated issues on the same templates, and the result of completing the key task with the keyboard alone on every site. On the keyboard pass, check that every element you need can be reached and operated, that focus is visible and that nothing traps it. An automated test covers only part of the WCAG criteria. What AA conformance actually requires is in WCAG 2.1 explained: principles, AA and 2.2 changes.
Sources
- Chrome for Developers, CrUX API: 28-day window, daily updates, p75, form factors, API key.
- Chrome for Developers, CrUX methodology: eligibility, browsers included.
- web.dev, Web Vitals: thresholds, 75th percentile, INP and TBT.
- Chrome for Developers, Lighthouse performance scoring: variability and metric weights.
- Lighthouse on GitHub, Score variability: median of five runs.
- Lighthouse on GitHub, Throttling: simulated throttling defaults.
- web.dev, Why lab and field data can be different: cache, device and network.
- Chrome for Developers, Lighthouse accessibility scoring: pass/fail audits.
- MDN, CSP: upgrade-insecure-requests: scope of the directive.
- Google Search Central, Understanding page experience: relevance and page experience.
- Google for Developers, About PageSpeed Insights: CrUX field data over 28 days, origin fallback, Lighthouse in a simulated environment.
Test data: methodology, benchmark record (CSV), per-run results, page selection from search results, diagnosis of our page, script, sources