Article 28.08.2026 3

Google said our site was not effective on mobile. The counters were to blame

Search Console flagged 102 not-effective addresses on mobile for our own site — and the same 102 green on desktop. The first hypothesis, a background animation, did not survive measurement. The culprits were the ad tags, and the costliest detail a second copy of the same 189 KB library. A full walkthrough with numbers and a six-step instruction.

Google said our site was not effective on mobile. The counters were to blame

Search Console lit up for our own site: 102 addresses "not effective" on mobile — and the very same 102 green on desktop. One site, one layout, two verdicts. We dug in, the first obvious hypothesis turned out to be wrong, and the culprit was something that sits on almost every site and that owners rarely think of as part of the site at all. Below is the whole investigation with measurements, and an instruction for checking and fixing your own.

What Google actually measures

The metric is INP — Interaction to Next Paint. Google describes it like this:

"INP is a metric that assesses a page's overall responsiveness to user interactions by observing the latency of all click, tap, and keyboard interactions that occur throughout the lifespan of a user's visit to a page."

Thresholds: good is 200 ms or less, needs improvement is 200 to 500 ms, poor is above 500 ms.

web.dev, INP documentation

The key thing for an owner to grasp: INP does not measure loading speed. It measures how long it takes from a tap until the screen visibly responds. A page can open in a second and still be "not effective" if, once open, it is busy with itself and cannot answer a finger.

And the second important thing: this is a field metric. Google collects it from real visitors, not from a lab test. So the report updates with a lag and over a rolling window — there will be no instant green after a fix.

Why mobile is red while desktop is green

The answer is boring and fully explains the gap: a phone's processor is four to eight times slower than a desktop one. The same chunk of work that takes 60 ms on a laptop and passes unnoticed stretches to 300–500 ms on a phone — and the person already sees the button "sticking". The layout has nothing to do with it: the code is identical, only the speed of running it differs.

The first hypothesis was wrong

Our home page has a background animation, and suspicion fell on it immediately — the way it will for most owners: "something on the site is moving, so that is what is slowing it down." Instead of switching it off and hoping, we measured three variants of the same screen: as is, with the animation off, and with third-party tags blocked.

What we measured was not a feeling but a specific quantity — main-thread blocking time: the sum of how much long tasks exceed 50 ms. While such a task runs, the browser cannot answer a tap, and this is exactly what INP is made of.

Main-thread blocking time The same screen every time, Pixel 5 emulation with the CPU throttled 4x as is 1782 ms animation off 1840 ms third-party tags blocked 378 ms Main-thread blocking time The same screen every time, Pixel 5 emulation with the CPU throttled 4x as is 1782 ms animation off 1840 ms third-party tags blocked 378 ms
PromoPilot's own measurement, 28 August 2026. Turning the animation off changes nothing; blocking the tags removes 79% of the blocking time.

The result settled the question. Turning off the animation gave nothing — 1840 ms against 1782 ms as is, a difference within the noise and formally even worse. Blocking third-party tags, meanwhile, cut blocking time from 1782 to 378 ms. 79% of the time during which the page could not respond to a finger was created neither by our code nor by the animation.

The real culprit

There were four tags in the <head>, all four the standard ones an owner installs and forgets: an analytics counter, an ad platform tag and two social-network pixels. All with the async attribute, all "non-blocking". Around 600 KB of third-party JavaScript in total.

Then came the thing this section is worth reading for. A 189 KB counter library was downloaded and executed twice.

The reason is mundane. We have two identifiers — analytics and advertising. For each, the platform issues a ready-made snippet with its own loading line, and the owner dutifully pastes both. But the library in them is one and the same: it serves every identifier through separate configuration calls. The second copy adds nothing — it is simply downloaded again, parsed again and executed again on that same slow mobile processor.

If you have both analytics and an ad account from the same platform, there is a good chance you have the same picture. It takes a minute to check — the method is in step 3 below.

Why "async" does not save you

This is the second place where intuition misleads. The async attribute means: "do not hold up HTML parsing, download in parallel." It honestly does its job — the page renders without waiting for the tag.

But once the file has downloaded, it still has to be executed, and it executes on the same single main thread that answers taps. async removes the parsing block but not the thread's busyness — and INP measures precisely that. Hence the familiar situation: the page appeared fast, every counter is "asynchronous", and the metric is red.

One more trap: deferral alone changes nothing

The obvious fix is to defer the tags until the browser is free. That is what we did. And measured.

Why deferring the load alone did not help Measured before the fix, after deferring the tags, and after removing the duplicate library before 2026 ms deferral only 2101 ms deferral + duplicate removed 1775 ms Why deferring the load alone did not help Measured before the fix, after deferring the tags, and after removing the duplicate library before 2026 ms deferral only 2101 ms deferral + duplicate removed 1775 ms
Deferring moves the work in time, it does not remove it. What produced the result was removing the second copy of a 189 KB library.

Blocking time after deferral alone came to 2101 ms against 2026 ms before — that is, slightly worse. The logic is simple: deferring moves the work in time, it does not remove it. The work has not gone anywhere, it just runs later — sometimes exactly when the person has already started tapping the screen.

What worked was something else: removing the second copy of the library. After that, blocking time fell to 1775 ms, and everything else followed — first paint from 1128 to 824 ms, server response from 669 to 335 ms.

What to do with your own site: six steps

Below is an order in which each step makes sense after the previous one. Each comes with a check showing you have passed it.

Step 1

Confirm the problem is yours

Open the Core Web Vitals section in Search Console and look at the mobile tab separately from the desktop one. Separately is the point: "phone red, desktop green" is the most common form of this problem, and looking only at the summary makes it easy to miss.

If the mobile tab is green, you can stop reading — you do not have this problem.

Check: you know how many not-effective addresses you have on mobile and from what date they became so. The date matters: it hints at what you installed back then.
Step 2

Measure instead of guessing

The main mistake at this step is to start switching off whatever looks heavy. We nearly switched off an animation that had nothing to do with it. Measure three variants of the same page: as is, without the suspect, and without third-party tags.

The most accessible way is Chrome DevTools: the Performance tab, CPU throttling at 4× with mobile emulation, record 10–15 seconds of the page's life and look at the long tasks. They are highlighted, and each one shows which file produced it.

Check: you have three numbers, not three opinions. If the gap between "as is" and "without the suspect" is under 10%, the suspect is innocent — keep looking.
Step 3

Check whether one library loads twice

This is the cheapest win on the list. Open the Network tab in DevTools, filter by js and scan the list: is the same file name there twice with different parameters in the address?

The typical case is an analytics counter and an ad tag from the same platform: different snippets, one file. Keep a single loading line, and set the second identifier up as a separate configuration call. Nothing is lost: the library serves both.

<!-- before: two snippets, the same library twice -->
<script async src="…/tag.js?id=ID-1"></script>
<script async src="…/tag.js?id=ID-2"></script>

<!-- after: one library, as many identifiers as you need -->
<script async src="…/tag.js?id=ID-1"></script>
<script>
  config('ID-1');
  config('ID-2');
</script>
Check: in the Network tab the library file appears exactly once, and data keeps arriving in both the ad platform and the analytics dashboard.
Step 4

Defer the tags without losing a single event

Only after step 3 — because deferral on its own does not help, as we measured. In combination, though, it frees up the critical first seconds.

The idea: move the external files out of <head> and load them on the first of three events — the main thread going idle, a 3-second timeout, or the first touch on the screen. Touch is mandatory in that list: if the person is already interacting with the page, the tag is needed immediately, otherwise you lose exactly the active session.

Events are not lost in the process, and this is the key detail. Tiny stub functions stay in <head> and queue every call; when the library finally loads, it replays the queue in full. That is how these snippets are designed — the queue is provided for by their own authors.

Check: open your site, click, and confirm that the visit and the event arrived in the analytics dashboard. If they did not, the stub is declared incorrectly, and that must be fixed before release.
Step 5

Re-measure, and do not expect instant green

After release, repeat the measurement from step 2 — you should see blocking time drop. The Search Console report, however, will not turn green at once: it is built on data from real visitors over a rolling window and updates with a lag of weeks.

That is normal and not a reason to roll the fix back or stack a second one on top. The lab measurement says it got better, so the field will confirm it later.

Check: blocking time in your own measurement has fallen, and analytics data keeps arriving in the same volume as before. Both halves are required: a fix that breaks conversion tracking is not a win.
Step 6

If it did not help — the reserve

Once the third-party tags are in order and the metric is still off, the next moves, in descending order of payoff: redundant counters that duplicate each other's purpose; unused CSS (on our home page 92% of the rules never apply); HTML caching, if the page is served with no cache at all.

Separately, it is worth asking honestly whether you need every counter you have connected. Each one is somebody else's code running on your visitor's phone while they wait for a tap to register.

Check: you can say what every tag on your site is for and who looks at the data it collects. Tags with no answer are the first candidates for removal.

What not to do

Switch off animation and visual design "just in case" We measured it: turning the animation off gave nothing, 1840 ms against 1782 ms. Removing the visible part of your site without checking its contribution is a reliable way to make the site worse and the metric no better.
Take comfort in the word "async" Asynchronous loading removes the parsing block, but the script still executes on the main thread. INP measures that thread's busyness, so "everything of ours is async" does not mean "everything of ours is fine".
Start with deferring the load Deferring moves the work rather than removing it: ours came to 2101 ms after deferral against 2026 ms before. Remove the excess first, then move what is left.
Expect a green report tomorrow The metric is field-based: it is collected from real visitors over a rolling window. A fix made today shows up in the report weeks later — that is not a reason to redo everything from scratch.

In short

"Not effective on mobile while desktop is green" almost always means one thing: the page is busy executing somebody else's code on a phone's slow processor. In our case third-party tags accounted for 79% of blocking time, and the most expensive small detail turned out to be a second copy of the same 189 KB library — loaded simply because the snippet is copied once per account.

If you do one thing right now: open the Network tab on your own site and see whether some counter file is being downloaded twice. It is a one-minute check, and it is free.

Check your site

The crawl reports heavy pages, blocking scripts and the rest of the technical findings — split by severity.

Frequently asked questions

What is INP in plain words?
It is the time from touching the screen to the moment the page visibly responds. Google counts 200 ms or less as good and more than 500 ms as poor. The metric assesses responsiveness, not loading speed: a page can open fast and still take a long time to answer a tap.

Why is a site not effective on mobile but effective on desktop?
Because a phone's processor is four to eight times slower than a desktop one. The same script that runs unnoticed in 60 ms on a computer stretches to 300–500 ms on a phone, and the person sees the delay. The code is identical — only the speed of running it differs.

Is it true that analytics slows a site down?
In our measurement third-party tags accounted for 79% of main-thread blocking time: 1782 ms with them against 378 ms without. That is not a reason to remove analytics altogether, but it is a reason to check how many tags you have, whether they duplicate each other, and when exactly they load.

Does async help on an analytics script?
Partly. The async attribute removes the HTML parsing block, so the page renders sooner. But the downloaded file still executes on the main thread, and INP measures that thread's busyness. An async script can spoil the metric just as an ordinary one does.

Can you defer counters without losing conversions?
Yes, if you leave stub functions in the head that queue calls until the library loads — that is how these snippets are designed. Be sure to include the first touch among the events that trigger loading, otherwise you can lose an active session. After release, verify that events are arriving.

How long until the Search Console report turns green after a fix?
Not immediately. The metric is collected from real visitors over a rolling window and updates with a lag of weeks. Rely on your own lab measurement: if blocking time has fallen, the field will confirm it later.

Sources

PromoPilot's own measurement, 28 August 2026: Pixel 5 emulation with the CPU throttled 4×, observation of long tasks and of tap latency on the live site.
web.dev, INP documentation: the definition, the good / needs improvement / poor thresholds, and the field nature of the measurement.
Google Search Console, the Core Web Vitals report: separate tabs for mobile and desktop devices.

Share:
Cascade Link Building

3 link tiers + crowd for maximum effect. Try it free!

Try Free
$30 Bonus on Registration

Start promoting your site now — the bonus is credited automatically

Get Bonus
How Cascades Work
L1 Articles on trusted platforms with DR 30–70
L2 L1 amplification via blogs and Web 2.0
L3 Indexation and support via profiles and comments
C Crowd links for natural profile
More details
Content