The True Cost of Analytics Scripts: Performance Benchmarks for 2026

8 read
Published

Most performance audits focus on your own code: image optimization, component lazy-loading, bundle splitting. The analytics script gets a free pass because it's "just tracking."

It shouldn't. We measured 10 providers across three metrics that determine real-world impact on your users. The spread is an order of magnitude.

The 2026 Analytics Performance Matrix

Six metrics tell the full story: Transfer Size (bytes over the wire), Decoded Size (what the browser parses and executes), Script Duration (pure V8 execution time), Task Duration (total main-thread blocking), Heap Impact (memory allocated), and Request Count (network overhead).

Analytics Script Benchmarks

by transfer size
Provider Transfer Decoded Script Task Heap Reqs LCP INP CLS
Vercel Analytics
1.6 KB
2.4 KB
0ms
5ms
+667KB
1
low
Plausible Analytics
1.9 KB
2.9 KB
1ms
6ms
+698KB
1
+1ms
low
Umami Analytics
2.4 KB
2.6 KB
0ms
5ms
+676KB
1
low
Fathom Analytics
3.0 KB
6.7 KB
1ms
9ms
+721KB
2
+1ms
low
Rybbit Analytics
9.0 KB
25.3 KB
2ms
7ms
+706KB
1
+2ms
low
Databuddy Analytics
10.6 KB
29.2 KB
1ms
7ms
+754KB
1
+1ms
low
Cloudflare Web Analytics
10.8 KB
30.4 KB
1ms
7ms
+736KB
1
+1ms
low
Segment
29.6 KB
107.0 KB
4ms
18ms
+1.2MB
3
+4ms
low
Matomo Analytics
60.4 KB
218.6 KB
5ms
16ms
+1.3MB
1
+5ms
medium
Google Analytics
153.9 KB
452.9 KB
13ms
26ms
+2.5MB
1
+13ms
medium
GTM + GA4
262.3 KB
754.6 KB
20ms
26ms
+4.2MB
2
+20ms
medium

Rybbit's 1,135ms load time and GA4's 585ms stand out immediately-but the decoded size column is where the real damage happens.

Why Decoded Size is the New Bottleneck

Developers fixate on gzipped transfer size. The browser doesn't execute gzip-it executes the decoded JavaScript. Those numbers are different.

Chrome's V8 engine does roughly 90% of parsing on background threads, so parse time alone isn't the culprit. Execution stays on the main thread. Every byte of decoded JS that contains function calls, closures, and event listeners runs on the same thread that handles user interactions.

The gap between providers is stark. GA4 at 452.9 KB decoded is 156x heavier than Plausible at 2.9 KB, and our benchmarks show it: GA4 burns 20ms of pure script execution and 33ms of total task time, vs 1ms script / 6ms task for Plausible. On mid-range mobile hardware, 400 KB of decoded JavaScript translates to roughly 150-250ms of main-thread contention (Addy Osmani, "Cost of JavaScript" 2024). GA4 also allocates +2.6 MB of heap memory compared to Plausible's +698 KB.

That contention directly degrades Interaction to Next Paint (INP)-Chrome's primary responsiveness metric since March 2024. If your analytics script fires during the first few seconds of a visit, you're burning INP budget on tracking code rather than user interactions.

Core Web Vitals Impact

The benchmark table above includes measured CWV estimates for every script: LCP impact (how much script execution delays rendering), INP risk (based on script weight and DOM observation), and CLS elements (injected visible elements that shift layout).

The heaviest scripts show consistent LCP delays. On a local page with no network variance, scripts like GA4 and Matomo add measurable rendering delays from pure execution time. Field numbers on real mobile connections will be worse - a script that costs 5-20ms of LCP on desktop can easily cost 30-50ms on mid-range mobile, which is the difference between passing and failing the 2.5s LCP threshold.

Scripts that combine heavy execution with MutationObserver usage (like GA4) carry a "high" INP risk - they not only block during initialization but continue to compete for the main thread on every DOM change.

Every 100 KB of gzipped JS that decodes to ~400 KB adds roughly 100-150ms of main-thread work on average mobile hardware. GA4 at 154.3 KB compressed sits right at that threshold.

The 2025 Fingerprinting Pivot

In February 2025, Google officially reversed its stance on digital fingerprinting, permitting canvas and WebGL fingerprinting in Google Ads provided advertisers disclose it in privacy policies. The UK's ICO called it "irresponsible".

GA4 is currently the only provider in our benchmark set using these techniques. The privacy implications have extensive coverage elsewhere. The performance cost gets less attention: canvas fingerprinting requires synchronous GPU readbacks, which add 10-30ms of latency directly to the main thread during script evaluation (Brave Privacy Blog). It's synchronous and blocks the main thread.

For a script already carrying 585ms of load time, an additional 10-30ms of synchronous GPU work is a rounding error in isolation. Combined with everything else GA4 does on initialization, it's one more reason the script consistently underperforms in field data.

Compression Wars: zstd vs the World

The compression story changed in 2025. Zstandard (zstd) reached baseline support across all major browsers with iOS 18 and macOS Sequoia joining Chrome 123+ and Firefox 126+. That means you can serve zstd-compressed assets to your entire user base.

The numbers: zstd decompresses at 600-800+ MB/s, roughly 3x faster than Brotli or Gzip (Cloudflare, 2024). Lower CPU overhead on mobile means faster decoding with less battery drain.

Cloudflare and Vercel have already shifted their analytics delivery to zstd. This is part of why Cloudflare Web Analytics (10.8 KB transfer, 30.4 KB decoded, 86ms load) punches above its weight in load time despite having a relatively large decoded footprint. The decompression cost is lower, and they've optimized the delivery pipeline.

If your self-hosted Matomo or custom analytics endpoint is still serving Brotli or Gzip, switching to zstd is a free win.

How Nuxt Scripts Loads Analytics

The standard analytics integration pattern-copy a snippet, paste it into a script tag-has predictable performance problems.

Dynamic injection hides from the preload scanner. Scripts created with document.createElement('script') are invisible to Chrome's preload scanner, which runs ahead of the parser to discover resources early. Dynamic injection means the browser can't queue the network request until the script that creates the element executes. That delay is typically 200-500ms (DebugBear, 2024).

Nuxt Scripts uses declarative loading, emitting the script as a standard script tag that the preload scanner can discover immediately-without blocking the initial render.

Initialization timing matters as much as load timing. Even a fast-loading script can hurt performance if it executes during the critical rendering window. Nuxt Scripts initializes analytics via requestIdleCallback by default, which defers execution until the browser's main thread has finished painting and handling any pending user input.

nuxt.config.ts
export default defineNuxtConfig({
  scripts: {
    registry: {
      plausibleAnalytics: { domain: 'your-domain.com' }
    }
  }
})

That single config line handles declarative injection, idle-time initialization, and SPA navigation tracking automatically. The manual alternative requires a plugin, process.client guards, a router watcher, and still probably gets the timing wrong.

Nuxt Scripts also supports first-party proxying, routing analytics requests through your own domain to bypass ad blockers. At 25-45% blocker adoption in many audiences (Blockthrough Ad-Block Report 2026), this restores significant data accuracy.

The 19-Second Death March

In emerging markets, average load time over 3G sits around 19 seconds (Google/HPBN). For users on that connection, a 154.3 KB GA4 script becomes a failure point. Unstable mobile connections drop requests. Expensive data plans mean users disable images and scripts. A script that takes 585ms to become interactive on a fast connection might simply never load.

A 0.1-second improvement in mobile load time increases retail conversion by 8.4% (Google/Deloitte, 2024). Swapping GA4 for Plausible-1.9 KB vs 154.3 KB on the wire-can recover 10-15 PageSpeed points and reduce Total Blocking Time by 100-200ms on mobile.

Sub-5 KB providers (Vercel Analytics, Plausible, Umami, Fathom) make sites accessible to users who would otherwise abandon them before the first interaction. For those users, this determines whether your site loads at all.

Making the Call

The benchmark data makes the performance winner clear: Vercel Analytics, Plausible, and Umami are in a different category from everyone else. If you don't need Segment's data routing, GA4's Google Ads integration, or Matomo's on-premise compliance features, there's no performance justification for using them.

If you do need those features, Nuxt Scripts' idle-time initialization and declarative loading reduce the damage. You can't make 452.9 KB of decoded JavaScript free, but you can stop it from running at the worst possible moment.

For the full breakdown of which provider fits which use case, see Choosing the Right Analytics for Nuxt. For privacy-specific comparisons including cookie policies and GDPR compliance, see Privacy-First Analytics Compared.