Image Load Lab

Guides Performance Lab Tested Oct 18, 2026 Lighthouse 13.5 · 48 live loads

A CLS of 1.0 From Our Own Stylesheet: What We Measured and Fixed

An external stylesheet plus the async AdSense script gave four of our pages a Lighthouse CLS of about 1.0. Inlining the same CSS brought it to 0.005 or less with the ads still loading.

On the evening of October 17, 2026, a routine Lighthouse check of this site returned a Cumulative Layout Shift (CLS) of about 1.0 on desktop and 0.50 to 0.59 on mobile for four of the five pages we test. Google calls anything above 0.25 “poor”. None of our images caused it: they all carry width and height, as described in our image dimensions test. Lighthouse named the page body, the main content area and the navigation as the elements that moved. In other words, the whole page jumped. We moved the theme’s stylesheet from a <link> into an inline <style> block, and the problem went away. Was the stylesheet really the cause, and what part did the advertising script play? This page shows the before and after numbers and a reproduction on the live site.

What we measured

Before the change, the theme (version 2.0.2) loaded one 20 KB stylesheet with a normal <link rel="stylesheet"> in the <head>. Google AdSense’s script loads async on every page. Version 2.0.3 printed the same CSS into a <style> element in the head instead. That was the only change between the two Lighthouse runs. The ad code was not touched: same script, same position, no delay.

We ran Lighthouse 13.5.0 three times per page and profile (mobile and desktop) on five pages before the change and again after it, and kept the median. Then, on October 18, we reproduced both versions on the live home page in Chrome 155.0.8059.82 driven by Playwright. Each load either kept the current inline styles or had them replaced on the fly with a link to the same style.css file, and either let the ad script load or blocked it. We ran six loads per combination and recorded every layout shift. See our methodology.

Lighthouse before and after

Grouped bar chart: with the external stylesheet, Lighthouse measured a CLS of about 1.0 on the home page, guide index, tool page and About page on desktop; after inlining the styles every page measured close to 0
Median Cumulative Layout Shift Lighthouse reported for five pages of this site before and after the theme’s styles were moved inline. Chart generated from the linked CSV.
Lighthouse 13.5.0, median of 3 runs per page and profile, October 17–18, 2026
Page Profile CLS, external stylesheet CLS, inline styles Score before → after
Home mobile 0.589 0.000 61 → 97
Home desktop 1.001 0.001 66 → 96
A guide mobile 0.065 0.065 97 → 98
A guide desktop 0.002 0.002 95 → 98
Guide index mobile 0.506 0.004 53 → 91
Guide index desktop 1.003 0.005 66 → 97
Tool page mobile 0.502 0.000 62 → 98
Tool page desktop 1.001 0.001 69 → 98
About mobile 0.502 0.000 63 → 98
About desktop 1.001 0.001 69 → 98

The fix took CLS from about 1.0 to 0.001–0.005 on desktop for the home page, the guide index, a tool page and the About page. On mobile those four pages went from 0.50–0.59 to 0.000–0.004. Their Lighthouse performance scores rose from 53–69 to 91–98, almost all of it from CLS.

One page never had the problem. The guide we test measured 0.002 on desktop and 0.065 on mobile, both before and after. That remaining 0.065 is a different shift: there, Lighthouse reported the article moving and listed a web font as one possible cause. It is under the 0.1 threshold Google calls “good”, and inlining the CSS did not change it. We do not know why the guide escaped the large shift that hit the other four pages.

Reproducing it on the live site

Live home page loaded in Chrome 155 with Playwright, 6 loads per combination
Viewport Theme styles Advertising script Loads with CLS above 0.1 Worst CLS
desktop external stylesheet ads loading 2 of 6 1.001
desktop external stylesheet ads blocked 0 of 6 0.001
desktop inline ads loading 0 of 6 0.002
desktop inline ads blocked 0 of 6 0.001
mobile external stylesheet ads loading 0 of 6 0.000
mobile external stylesheet ads blocked 0 of 6 0.000
mobile inline ads loading 0 of 6 0.000
mobile inline ads blocked 0 of 6 0.000

The large shift came back only when both ingredients were present. With the external stylesheet and the ad script loading, two of six desktop loads measured a CLS of about 1.0. In both, the largest shift was again attributed to the body, main and navigation elements. Blocking the ad script made those shifts disappear (worst load 0.001). With inline styles, no load went above 0.002, with or without ads.

It is intermittent. Four of the six “bad” desktop loads were clean. A single test run can therefore catch the problem or miss it, which matches what we saw in our Lighthouse variance test.

On mobile we could not reproduce it. All 24 mobile loads measured 0.000, although Lighthouse had reported 0.50–0.59 on mobile the evening before. Our reproduction did not throttle the network or the CPU, and ad behaviour differs between loads and devices, so this is not a contradiction. Our reproduction just did not trigger the shift on mobile.

A minimal reproduction that failed

We also tried to rebuild the problem without real ads. On a local test page with the same stylesheet, we delayed the CSS by 800 ms and added a small async script that forces a layout calculation (it reads document.body.offsetHeight). We tested six combinations: slow or fast stylesheet, async or deferred script, layout-reading or harmless script, and inline CSS. Each ran five times on desktop and five on mobile. CLS was 0 in all 60 loads. So “an async script runs before the stylesheet arrives” is not enough on its own. Something specific in what the ad script does triggered it, and we could not isolate what.

Our interpretation, which we have not proven: a shift of about 1.0 where the body, main area and navigation all move looks like a page painted once without its styles and then re-laid out when the stylesheet arrived. Chrome normally waits for stylesheets in the head before painting. Inlining the CSS removes that window entirely, because the styles arrive with the HTML.

What this means

  • If Lighthouse blames body, main or nav for a big shift, suspect how the CSS is delivered, not the images. Image shifts are usually attributed to the image or to the content right below it.
  • Test with the real third-party scripts loading. Our minimal page and our ad-blocked loads looked perfect. Only the full page with ads showed the shift.
  • Run several loads. With two bad loads in six, the 75th-percentile value that Google uses for field data would fall in the “poor” range, while a single lucky run would have passed.
  • Inlining a small stylesheet is a legitimate fix. Its cost, a larger HTML document on every page, is measured in our inline vs external CSS test.
  • Do not “fix” CLS by delaying or hiding ads. We left the ad code exactly as Google provides it, and the fix did not need any change to it.

Practical conclusion

On this site, an external 20 KB stylesheet plus the asynchronous AdSense script produced intermittent whole-page shifts with a CLS of about 1.0. Moving the same CSS inline brought CLS to 0.005 or less on every affected page, with the ads still loading. A minimal reproduction without the real ad script did not show the problem, so test layout stability on the real page, with its real scripts, several times.

Limitations

One site, one theme and one ad configuration. Three Lighthouse runs per page before and after, and six live loads per combination, all from the same machine and connection. Ad responses vary between loads, so another day may give other proportions. We did not test critical-CSS tools that inline only part of a stylesheet.

Data and files

Download lighthouse-cls-before-after.csv (10 rows, 0.4 KB) · Download async-script-cls-live.csv (48 rows, 3.3 KB) · Download async-script-cls.csv (12 rows, 0.8 KB) · Method: testing methodology.