Repository: GoogleChrome/lighthouse (JavaScript)

Issue:
Viewport audit does not flag for initial-scale < 1
### FAQ

- [X] Yes, my issue is not about [variability](https://github.com/GoogleChrome/lighthouse/blob/main/docs/variability.md) or [throttling](https://github.com/GoogleChrome/lighthouse/blob/main/docs/throttling.md).
- [X] Yes, my issue is not about a specific accessibility audit (file with [axe-core](https://github.com/dequelabs/axe-core) instead).

### URL

https://pro-truck.com/

### What happened?

(Note related to #12884 )

This has the following meta viewport in the HTML:

```html
<meta name="viewport" content="width=device-width, initial-scale=0.9">
```

The `initial-scale=0.9` causes the 300 second tap delay impacting FID and INP as noted in this recent blog post: https://www.phpied.com/fixing-inp-with-a-viewport-tag/

The [current audit](https://github.com/GoogleChrome/lighthouse/blob/main/core/audits/viewport.js) checks `isMobileOptimized` which only checks for the presence of `initial-scale`:

https://github.com/GoogleChrome/lighthouse/blob/6eba650b5224ce2a504971171aa13b604765a89d/core/computed/viewport-meta.js#L38

We should enhance that to also check that the initial-scale is not < 1 as that also triggers the slowness.

### What did you expect?

Audit should fail

### What have you tried?

Details above.

### How were you running Lighthouse?

PageSpeed Insights

### Lighthouse Version

10.3.0

### Chrome Version

114

### Node Version

N/A

### OS

N/A

### Relevant log output

```shell
https://pagespeed.web.dev/analysis/https-pro-truck-com/wohl517q6h?form_factor=mobile
```



Discussion:
Interesting, didn't realize this was dependent on the scale value. I do wonder if this change makes sense for SEO ranking as well though.

If our SEO advice is slightly different from our perf advice then we will need two different audits for this now.
FYI, @yoavweiss dug this [up from the Chrome code](https://source.chromium.org/chromium/chromium/src/+/refs/heads/main:third_party/blink/renderer/core/frame/web_frame_widget_impl.cc;drc=1b9ee37d9e583adb8b4f492115bdb8fd268e8188;bpv=1;bpt=1;l=4278)

> I do wonder if this change makes sense for SEO ranking as well though.
>
> If our SEO advice is slightly different from our perf advice then we will need two different audits for this now.

Given that [Search is retiring the mobile friendly test](https://developers.google.com/search/blog/2023/04/page-experience-in-search) and leaving it up to other tools (they recommend Lighthouse!), maybe it's time to remove it from SEO audit at same time and therefore avoid any conflict or duplication of audits?
We are going to do this, we are not so concerned about the effects on the SEO category.

https://chromium.googlesource.com/chromium/src/+/refs/heads/main/docs/speed/metrics_changelog/2021_05_fid.md
our current check is this:

```js
    const isMobileOptimized = Boolean(viewportProps.width || viewportProps['initial-scale']);
```

we can change it to see if initial-scale is truthy and a number >= 1.



Patch:
diff --git a/core/computed/viewport-meta.js b/core/computed/viewport-meta.js
index 44fa9d5878c8..c3304e010386 100644
--- a/core/computed/viewport-meta.js
+++ b/core/computed/viewport-meta.js
@@ -35,7 +35,17 @@ class ViewportMeta {
     }
 
     const viewportProps = parsedProps.validProperties;
-    const isMobileOptimized = Boolean(viewportProps.width || viewportProps['initial-scale']);
+    const initialScale = Number(viewportProps['initial-scale']);
+
+    if (!isNaN(initialScale) && initialScale < 1) {
+      return {
+        hasViewportTag: true,
+        isMobileOptimized: false,
+        parserWarnings: warnings,
+      };
+    }
+
+    const isMobileOptimized = Boolean(viewportProps.width || initialScale);
 
     return {
       hasViewportTag: true,


Test patch:
diff --git a/core/test/computed/viewport-meta-test.js b/core/test/computed/viewport-meta-test.js
index 4115c6129649..40c1b9d4509a 100644
--- a/core/test/computed/viewport-meta-test.js
+++ b/core/test/computed/viewport-meta-test.js
@@ -52,6 +52,14 @@ describe('ViewportMeta computed artifact', () => {
     assert.equal(parserWarnings[1], 'Invalid values found: {"initial-scale":"microscopic"}');
   });
 
+  // eslint-disable-next-line max-len
+  it('is not mobile optimized when a viewport contains an initial-scale value lower than 1', async () => {
+    const viewport = 'width=device-width, initial-scale=0.9';
+    const {isMobileOptimized} =
+      await ViewportMeta.compute_(makeMetaElements(viewport));
+    assert.equal(isMobileOptimized, false);
+  });
+
   it('is mobile optimized when a valid viewport is provided', async () => {
     const viewports = [
       'width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=1',