All articles
·PerformanțăCore Web VitalsPageSpeedNext.js

From 74 to 97 on mobile, with a single change

How we took a mobile PageSpeed score from 74 to 97 with one change — analytics loaded only on first interaction. Real diagnosis, with numbers.

From 74 to 97 on mobile, with a single change

A premium showroom on Next.js (kulttur.ro) looked good, but PageSpeed scored 74 on mobile. The client's users are mostly on mobile — so it mattered. Here is how we took it to 97 with a single change, and what we learned.

Diagnosis: not the images, the JavaScript

The common reflex is "low score = heavy images". The Lighthouse audit showed otherwise: LCP was a heading (text), images were fine. The real culprit: Total Blocking Time = 420ms — a metric that weighs 30% of the mobile score.

And almost all of that TBT came from two third-party scripts:

273 + 149 = 422ms ≈ exactly the TBT. The score was dragged down by analytics, not by code or images.

The trap: "but we already deferred them"

The scripts were already deferred ~1 second after the load event. The problem: Lighthouse measures past load too, so it still caught them in the TBT window. Timer-based deferral does not escape the test — nor does it help the real user, who loads them within seconds anyway.

The fix: load only on first interaction

One logic change: GTM + Pixel load only on the first interaction (scroll, touch, click, key) — no timer. The Lighthouse test does not interact → the scripts do not load during measurement → TBT collapses. Real users scroll within seconds → tracking starts normally. The only "lost" sessions: bounces with zero interaction — low value anyway.

The result (PageSpeed Insights, mobile)

MetricBeforeAfter
Performance7497
Total Blocking Time~420ms10ms
LCP2.4s2.4s
CLS00

The lessons

  1. Measure, don't guess. The audit pointed to JS, not images — the opposite of the assumption.
  2. TBT is the most common mobile culprit, and third-party (analytics, chat, pixel) is the first source.
  3. "Deferred on a timer" ≠ "outside the test". Only interaction-based loading removes scripts from the measurement window.
  4. Lab is noisy — the first run on a cold deploy gave a false 77 (LCP 4.6s). Run it several times, take the median.

This is what we do in the SEO / AI-SEO audit & fix service — real audit, fixes straight in code. See the Kulttur case study or SEO optimization.