> ## Documentation Index
> Fetch the complete documentation index at: https://docs.vortexiq.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Layout Stability, Website Performance (PageSpeed + CrUX)

> Layout Stability for Website Performance (PageSpeed + CrUX) stores. Tracked live in Vortex IQ Nerve Centre. How to read it, why it matters, and how to act ...

**Metrics type:** [Supporting Metrics](/nerve-centre/overview#metrics-types-explained)  •  **Category:** [Website Performance](/nerve-centre/connectors#connectors-by-type)

## At a glance

> **Cumulative Layout Shift at the 75th percentile.** Measures unexpected visual movement of page content during the page lifecycle, expressed as a unitless score (not milliseconds, not pixels). Calculated as `impact fraction × distance fraction` summed across all unexpected shifts. **Google's "good" threshold is 0.1**, sites at p75 CLS under 0.1 pass this CWV; over 0.25 is "poor". Layout shift is the most viscerally annoying performance failure: customers tap a button, the layout shifts mid-tap, they tap the wrong thing. The metric directly correlates with rage-clicks, accidental cart-removals, and trust loss.

|                                   |                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             |
| --------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **What it counts**                | The 75th-percentile of `cumulative_layout_shift` measurements across all real-user page-loads in the 28-day CrUX window. Score is calculated as the sum of all "unexpected" layout shifts during the page lifecycle. **A shift counts as unexpected** unless it occurs within 500ms of a user input (clicks, taps, keypresses are excluded as expected user-driven shifts).                                                                                                                                                                                                                                                                                                                                                 |
| **The score formula**             | Per shift: `layout_shift_score = impact_fraction × distance_fraction`. Impact fraction is the proportion of viewport affected; distance fraction is how far elements moved relative to viewport. **Example**: a banner shifting 33 percent of the viewport, 25 percent of the way down, scores `0.33 × 0.25 = 0.08`. CLS is the sum across all shifts in the page session.                                                                                                                                                                                                                                                                                                                                                  |
| **Sample type**                   | **Field data** sourced from CrUX. Lab equivalent: [`psi_lab_cls`](/nerve-centre/kpi-cards/website-performance/lab-layout-stability).                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        |
| **Google thresholds**             | **Good: ≤ 0.1**. **Needs improvement: 0.1-0.25**. **Poor: > 0.25**.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         |
| **Common ecommerce CLS patterns** | (a) **Hero banner without aspect-ratio reservation**: image loads, layout shifts to accommodate. (b) **Web font swapping mid-render**: text reflows when custom font replaces fallback. (c) **Late-loading widgets**: Klaviyo popup, chat widget, currency switcher push content as they mount. (d) **Ad placements without size reservation**: ad slots size themselves at fill time, pushing content. (e) **Cookie-consent banners**: appear after first paint, pushing content. (f) **Image upload via responsive `<img>` without explicit dimensions**: browser doesn't know size until image loads.                                                                                                                    |
| **Optimisation playbook**         | (1) **Declare aspect-ratio CSS** on every image and video container: `aspect-ratio: 16 / 9` reserves space before image loads. (2) **Use `width` and `height` attributes** on `<img>` tags so browser can compute aspect ratio. (3) **Preload web fonts with `<link rel="preload">`** and use `font-display: optional` to avoid swap. (4) **Reserve space for late-loading widgets**: explicit min-height on chat widget container, Klaviyo popup container. (5) **Reserve space for ad slots**: `min-height` matching the ad creative's size. (6) **Use `position: fixed` for cookie banners** to avoid pushing content. **Each fix typically reduces CLS by 0.02-0.06**; cumulatively can take a 0.18 score down to 0.05. |
| **Sample size threshold**         | CrUX p75 requires sufficient real-user volume (\~1,000+ page-loads per device per 28 days).                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 |
| **Currency**                      | n/a, this is a unitless score.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              |
| **Time window**                   | `28D` (CrUX-fixed).                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         |
| **Alert trigger**                 | `> 0.1` (Google's good threshold). Sub-thresholds: amber 0.1-0.25, red > 0.25.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              |
| **Sentiment key**                 | `psi_cls`                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |
| **Roles**                         | owner, marketing, operations                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |

## Calculation

Calculated automatically from your Website Performance (PageSpeed + CrUX) data. See the At a glance summary above for what the metric tracks and the worked example below for a typical reading.

## Worked example

A UK-based BigCommerce fashion store with 480,000 mobile page-views over 28 days, Stencil theme with hero banner + Klaviyo popup + chat widget + cookie consent banner. Snapshot Wednesday 15 May 26.

| Layout shift event                                    | Impact fraction | Distance fraction | Score | Cumulative CLS |
| ----------------------------------------------------- | --------------: | ----------------: | ----: | -------------: |
| Hero banner image loads (no aspect-ratio set)         |            0.42 |              0.18 | 0.076 |          0.076 |
| Web font swap (Inter loading after fallback)          |            0.85 |              0.04 | 0.034 |          0.110 |
| Cookie consent banner appears (top-fixed-then-pushes) |            0.18 |              0.21 | 0.038 |          0.148 |
| Klaviyo popup mounts (300ms post-load)                |            0.12 |              0.16 | 0.019 |          0.167 |
| Chat widget icon appears (1.2s post-load)             |            0.04 |              0.08 | 0.003 |          0.170 |
| **Page-level CLS (mobile p75)**                       |                 |                   |       |      **0.170** |

What the per-shift view is telling us:

1. **The 0.170 origin p75 CLS is in the "needs improvement" band** (0.1-0.25). Not poor, but failing the good threshold and contributing to the all-three CWV pass-rate failure. The shifts compound: each individual shift might feel minor but the user experience is "the page jumps around for 1.5 seconds while loading".

2. **The hero banner is the biggest single contributor (0.076).** With no aspect-ratio set on the banner container, the browser doesn't reserve space until the image arrives; when it does, content below the banner pushes down by the banner's height. **One-line fix in CSS**: `.hero-banner { aspect-ratio: 16 / 9; }`. Estimated post-fix: 0.000 contribution from this shift; total CLS drops to 0.094.

3. **The web font swap (0.034) is the second-biggest contributor.** When custom fonts (Inter, Poppins, etc.) load asynchronously, text initially renders in the fallback (Helvetica, Arial, system-ui), then swaps to the custom font when ready, causing every text element to potentially reflow. **The fix has two parts**: (a) `<link rel="preload" as="font" type="font/woff2" crossorigin>` for critical fonts; (b) `font-display: optional` so if the font isn't ready in 100ms, fallback is used permanently for that page-load. Estimated post-fix: 0.005-0.010 contribution.

4. **Cookie consent banner (0.038)** appears after first paint and pushes all content down. **Fix**: position the banner with `position: fixed; bottom: 0` so it overlays content rather than displacing it. Most modern cookie-consent libraries support this layout; the merchant just needs to enable it.

5. **Klaviyo popup (0.019)** mounts as a JS-driven DOM insertion 300ms after page load. **Fix**: reserve a fixed-position container for the popup so the mount doesn't displace surrounding content. Klaviyo's modern popup config supports this.

6. **Chat widget icon (0.003)** is small but worth noting. Most chat widgets (Tidio, Intercom, Zendesk Chat, Drift) provide a `position: fixed` mount option; ensure that's the configured pattern.

7. **Cumulative impact of all fixes**: 0.170 → 0.025 (good band). Total work: \~1-2 days of focused CSS + integration config changes. **The CLS fixes have the highest leverage-to-effort ratio of all CWV metrics**: the underlying causes are well-understood and the fixes are mostly declarative.

The diagnostic flow when this card flags amber or red:

1. **Open Chrome DevTools Performance tab** and record the page load. The "Layout Shifts" lane shows each shift with timestamp, affected elements, and score contribution.
2. **Use the Web Vitals Chrome extension** to see live CLS as you scroll/interact with the page.
3. **Identify the largest single shift.** [`crux_cls_distribution`](/nerve-centre/kpi-cards/website-performance/layout-shift-distribution) surfaces the distribution; the worst single shift typically dominates the CLS score.
4. **Check for late-loading widgets.** [`psi_third_party_cost`](/nerve-centre/kpi-cards/website-performance/third-party-cost) shows third-party scripts; many of them mount UI after first paint.
5. **For the demo's BC sandbox**, the hero banner is the most likely dominant cause; fix it first.

The rapid-response playbook for engineering:

| Time horizon             | Action                                                                              |
| ------------------------ | ----------------------------------------------------------------------------------- |
| First 1 hour after alert | Identify the largest single shift in DevTools.                                      |
| First 4 hours            | Apply aspect-ratio CSS fix to the worst element.                                    |
| First 24 hours           | Apply font-display + preload for web fonts. Reserve space for late-loading widgets. |
| First 7 days             | Field CLS partial movement. Confirm direction.                                      |
| Day 28                   | Field CLS fully reflects fix. Move to next-priority shift if needed.                |

## Sibling cards merchants should reference together

| Card                                                                                              | Why merchants reach for it                                                |
| ------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------- |
| [`crux_cls_distribution`](/nerve-centre/kpi-cards/website-performance/layout-shift-distribution)  | CLS good/needs-improvement/poor distribution.                             |
| [`crux_cls_trend`](/nerve-centre/kpi-cards/website-performance/layout-stability-over-time)        | CLS over time; drift detection.                                           |
| [`psi_lab_cls`](/nerve-centre/kpi-cards/website-performance/lab-layout-stability)                 | Lab CLS, the synthetic equivalent.                                        |
| [`crux_lcp_p75`](/nerve-centre/kpi-cards/website-performance/page-load-speed)                     | Sister CWV; pair for the load + stability picture.                        |
| [`crux_inp_p75`](/nerve-centre/kpi-cards/website-performance/click-responsiveness)                | Sister CWV.                                                               |
| [`psi_cwv_pass_rate`](/nerve-centre/kpi-cards/website-performance/speed-test-pass-rate)           | All-three CWV gate. CLS failing alone fails the gate.                     |
| [`psi_perf_score_summary`](/nerve-centre/kpi-cards/website-performance/performance-score-summary) | Composite score. CLS is 25 percent of the weight.                         |
| [`psi_third_party_cost`](/nerve-centre/kpi-cards/website-performance/third-party-cost)            | Third-party scripts; common cause of late-loading content shifts.         |
| [`psi_image_optimisation`](/nerve-centre/kpi-cards/website-performance/image-optimisation)        | Image optimisation; correctly-dimensioned images are the biggest CLS fix. |
| [GA4 `ga_engaged_sessions`](/nerve-centre/kpi-cards/google-analytics/engaged-sessions)            | Engagement metric; CLS-heavy pages reduce engagement.                     |

## Reconciling against the vendor's own dashboard

**Where to look in PageSpeed Insights / GSC / CrUX's own dashboards:**

* **[PageSpeed Insights](https://pagespeed.web.dev)**, field section shows origin-level p75 CLS under "Cumulative Layout Shift".
* **[Google Search Console → Core Web Vitals](https://search.google.com/search-console)**, surfaces URL groups failing CLS threshold.
* **[Web Vitals Chrome extension](https://chrome.google.com/webstore/detail/web-vitals/ahfhijdlegdabablpippeagghigmibma)**, measures CLS live as you scroll/interact.
* **Chrome DevTools → Performance tab**, visualises layout shift events with affected elements highlighted.

**Why the Vortex IQ CLS may legitimately differ from PSI / GSC:**

| Reason                                                                                                                                                                                                                              | Direction                       | What to do                                       |
| ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------- | ------------------------------------------------ |
| **Window timing.** Vortex IQ refreshes daily; CrUX dataset has 1-2 day lag.                                                                                                                                                         | Vortex IQ **lags** for 1-2 days | Wait for next refresh.                           |
| **Origin vs URL.** Different aggregations for different views.                                                                                                                                                                      | Different aggregation           | Use per-URL view for direct comparison.          |
| **Form factor.** Vortex IQ defaults to mobile.                                                                                                                                                                                      | n/a if both mobile              | Confirm form factor.                             |
| **CLS definition update May 2021.** Google updated the CLS calculation in May 2021 to use "session windows" (1-second gaps reset the cumulative counter). Sites comparing year-over-year before the update see a methodology break. | Either direction                | Anchor comparisons within the post-May-2021 era. |

**Cross-connector reconciliation:**

| Comparison                                                                                         | Expected relationship             | When divergence is legitimate                                                                                                                                     |
| -------------------------------------------------------------------------------------------------- | --------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `crux_cls_p75` ↔ [`psi_lab_cls`](/nerve-centre/kpi-cards/website-performance/lab-layout-stability) | Field and lab directionally agree | Lab measures one synthetic load; field measures real-user variation. Persistent gaps suggest CLS depends on user behaviour (scroll patterns, interaction timing). |
| `crux_cls_p75` ↔ Internal RUM CLS measurement                                                      | Should align within 0.02-0.05     | Cohort differences (CrUX is opted-in Chrome users; RUM samples your traffic). Modest divergence is normal.                                                        |

**Quick rule for support tickets:** if a merchant says *"my page doesn't move at all but you're showing CLS of 0.18"*, capture the page load in DevTools Performance with a clean cache and slow-3G throttling. CLS issues hide in cache-warm conditions; cold cache reveals them.

## Known limitations / merchant FAQs

**My CLS is 0.18 but the page doesn't look like it's jumping. Why?**

CLS accumulates across the entire page lifecycle, not just first paint. Many sites have small shifts spread across the load that individually feel minor but sum to a high score: hero image loading (0.05), font swap (0.03), late widget mounts (0.04), cookie banner (0.04), ad slot fill (0.02) = 0.18 cumulative even though no single shift is dramatic. Use Chrome DevTools' Performance tab to see each individual shift; you'll see all of them.

**Why is CLS so much harder to debug than LCP?**

CLS depends on timing, network conditions, and user interaction. LCP is largely deterministic (slow network = slow LCP); CLS varies by what the user does and when third-party scripts arrive. **The same page can have CLS 0.05 with a fast cached load and CLS 0.30 with a cold-cache slow load**. Reproducing CLS issues requires testing under varied conditions.

**Should I worry about CLS on pages that don't get search traffic?**

Less. CLS affects ranking on traffic Google cares about (organic search). For internal admin pages, conversion-flow pages (cart, checkout), or paid-traffic-only landing pages, CLS matters for user experience but not for SEO. **Focus CLS optimisation on high-organic-traffic templates first** (homepage, category, PDP); de-prioritise on transactional pages.

**Will adding aspect-ratio CSS to all my images break the layout?**

Generally no, with one caveat. `aspect-ratio` reserves space matching the declared ratio; if the actual image is a different ratio, the image may be letter-boxed or stretched depending on `object-fit`. **Best practice**: set `aspect-ratio` per image based on the actual image dimensions (using inline style attributes if dimensions vary), or standardise image dimensions at upload time. For BC themes with merchant-uploaded product images of varying dimensions, the `width` and `height` HTML attributes (not CSS `aspect-ratio`) work better because they accept per-image values.

**My CLS is fine on most pages but bad on the homepage. Is that OK?**

Depends on traffic share. If the homepage is 10 percent of traffic, the homepage's bad CLS contributes proportionally to the origin-level pass rate. If the homepage is 40 percent of traffic, fixing it lifts the origin pass rate noticeably. **The fix decision is the same**, fix the worst-offending page, but the urgency scales with traffic share.

**Cookie consent banners are a legal requirement. Can I avoid the CLS impact?**

Yes, with proper layout. **Position the banner with `position: fixed; bottom: 0` (or `top: 0`)** so it overlays content rather than displacing it. Most modern cookie consent libraries (OneTrust, Cookiebot, BC's built-in consent) support this layout pattern. **Avoid the legacy "push content down" pattern** which was common 5 years ago but is now considered both UX-poor and CLS-bad.

**Will Lighthouse score CLS the same as the field measurement?**

Approximately, but with caveats. Lab Lighthouse measures CLS during a single synthetic page-load with controlled conditions; field CrUX measures the distribution across all real-user sessions including those with interactions, scrolling, and multiple navigations. **Lab CLS is typically lower than field CLS** because lab can't capture user-interaction-triggered shifts. Use lab as a development tool; field as the truth source.

**Can Vortex IQ identify the specific element causing the worst shift?**

Yes, indirectly. Lighthouse's "Avoid large layout shifts" audit (surfaced via [`psi_top_opportunities_ms`](/nerve-centre/kpi-cards/website-performance/top-opportunities)) lists shifting elements with their score contributions. The Vortex IQ audit module flags the top 3 shifting elements per template.

**My BC site's CLS got worse after I added a chat widget. What can I do?**

Most chat widgets default to a `position: relative` mount that can shift content. Switch the widget to `position: fixed` mode (Tidio, Intercom, Zendesk Chat all support this) and reserve a fixed-pixel container. Alternatively, configure the widget to load only after first paint (Klaviyo + most chat widgets support `display_after_seconds: 3` or similar), by then the user has already seen and engaged with the page, and the widget mount doesn't disrupt their experience.

**How long does it take to fix CLS from 0.18 to 0.05?**

Usually 1-3 days of focused work for a typical Stencil-themed BC site, longer for custom-built sites. The fixes are mostly declarative CSS changes plus widget-config tweaks; the constraint is identifying every contributing shift, not implementing each fix.

***

### Tracked live in Vortex IQ Nerve Centre

*Layout Stability* is one of hundreds of KPI pulses Vortex IQ tracks across Website Performance (PageSpeed + CrUX) and 70+ other ecommerce connectors. Nerve Centre runs the detection layer; Vortex Mind investigates the cause when something moves; Ask Viq lets you interrogate any number in plain English.

[Start for free](https://app.vortexiq.ai/login) or [book a demo](https://www.vortexiq.ai/contact-us) to see this metric running on your own data.
