Fixing INP with a VIEWPORT tag

July 12th, 2023. Tagged: performance

So I woke up yesterday being scolded by Google. An email from Google Search Console Team with subject "Core Web Vitals INP issues detected on your site". Huh?!

It was about this WordPress-powered site that you're reading now (phpied.com). The Interaction to Next Paint metric (INP for short) was in the "Needs improvement" category as the average of all interactions Google knows about from 138 pages (only?!) is 255ms, which is over the good threshold of 200ms. Wait, what? This is a static blog, no onclick event listeners or anything, how can it be?

google search console

Yes, WordPress has a onload/DOMContentLoaded even listener that initializes emojis (of all things!). But it's hardly possible that it takes this long and people click on links 0ms after they appear. I was baffled.

I asked for help in the Web Performance Slack. Barry Pollard offered guidance and a WP/INP-related pointer and Juan Ferreras jumped to debug.

Turns out Chrome (emulating a mobile browser) takes about 250ms to "process" a simple click on the page. With no event listeners attached. How is this possible? Tried an even simpler page. Same thing. Tried google.com... 20ms. Huh?

debugging before the fix showing 250ms click

Then Juan had an insight. Is this the ole delay when the mobile browser doesn't know about clicks? But it translates taps to clicks after a bit of a wait to see whether the user meant a double-tap to zoom. Turns out, yes! A page can opt out of the wait by using a viewport tag. However the viewport tag I had on the blog was 0.9 scale for whatever reason. Which disqualifies it from the opt out.

So the fix:

viewport code fix

And the result after the fix:

debugging after the fix showing 20ms click

Finally, telling the Google search console that I fixed the problem and now we wait.

28 days wait to verify the fix

Conclusions and remarks

1. This is the easiest INP fix you can ever do. If you don't have a viewport tag on your mobile site (or regular site loaded by mobile browsers), go add one today. Better INP, happier users. 250ms+ interactions down to 20ms or less.

You can use the tag from the doc:

<meta name="viewport" content="width=device-width,user-scalable=no">


... or the one I used:

<meta name="viewport" content="width=device-width,initial-scale=1.0">

The one mentioned in the doc is not user-friendly as it prevents user from zooming.

2. The web.dev doc talks about a 300ms delay. Looks like this should be updated to 200ms in many cases.

3. Note how I was looking at the second click for debugging. This is a tip from Barry, the first click may have some profiler overhead. Didn't matter in my case but there is a small diff.

Updates

1. Scratch the `user-scalable=no` for a11y purposes

2. Chromium bug to start gathering data in the wild https://bugs.chromium.org/p/chromium/issues/detail?id=1464498

3. Lighthouse bug to warn folks of non-1 scale https://github.com/GoogleChrome/lighthouse/issues/15266

Tell your friends about this post on Facebook and Twitter

Sorry, comments disabled and hidden due to excessive spam.

Meanwhile, hit me up on twitter @stoyanstefanov