At a glance
- Put width and height on every image and video, or use CSS aspect-ratio.
- Give widgets, frames and promotional slots a minimum height, and keep it when nothing loads.
- Place late content lower on the page, or overlay it instead of inserting it.
- Animate with transform, and match web font fallbacks with size-adjust.
Step 1: size every image and video
web.dev's first rule is to "always include width and height size attributes on your images and video elements". Modern browsers use the two values to reserve the right aspect ratio before the file arrives, even when CSS makes the image responsive. For game tiles, set the attributes on each <img>; for banners whose ratio changes by breakpoint, use <picture> sources with their own dimensions or a CSS aspect-ratio per breakpoint.
Step 2: reserve slots for widgets and frames
Review carousels, social embeds, odds widgets, chat launchers and payment frames often decide their height after they load. web.dev recommends reserving space in the initial layout, for example with a min-height, and not collapsing that space when nothing loads, because removing it causes a shift of its own.
- Measure the most common rendered height of each widget on mobile and desktop and use it as the minimum.
- For payment frames, agree a fixed container size with the provider and let the frame scroll inside it if needed. See payment widget performance.
- Show a skeleton of the same size while the widget loads, not a small spinner that grows.
Step 3: stop inserting content above the reader
web.dev notes that dynamically injected content "closer to the top of the viewport usually causes greater layout shifts". Common casino cases are promotional strips, "app available" prompts, consent banners and geolocation or age notices inserted at the top after the first paint. Options, in order of preference:
- Render the element in the initial HTML so it is part of the first layout.
- Reserve its slot from the first paint.
- Show it as an overlay or at the bottom of the viewport, where it does not move other content.
Safer gambling messages and licensing notices that a market requires should be visible from the first paint. Building them into the template, rather than injecting them, is better for players and for stability.
Step 4: animate without moving layout
Animate with transform rather than properties such as top and left, which trigger layout. This applies to carousels, ticker strips, jackpot counters and expanding sticky footers. Respect the reduced motion setting with the prefers-reduced-motion media feature; see accessibility and performance.
Step 5: tame web font swaps
When a web font arrives and replaces the fallback, text can reflow if the two fonts have different sizes. web.dev suggests font-display: optional to avoid a re-layout, size-adjust to match the fallback to the web font and preloading critical fonts. Promotional headings in display fonts are the usual offenders on casino pages.
Step 6: keep pages eligible for the back/forward cache
Pages restored from the bfcache do not repeat their load-time shifts. web.dev's bfcache guide says the most important step is never to use the unload event and to use pagehide instead. It also notes that pages sent with Cache-Control: no-store may not be eligible.
Checking the fix
| Check | Tool | Pass condition |
|---|---|---|
| Load, scroll and wait for 10 seconds on a throttled mobile profile | Chrome DevTools Performance panel | No layout shift markers outside user input |
| Repeat logged in and logged out, and per market variant | Same | Same result for each variant |
| Field CLS for the template | Search Console or your own field data | 75th percentile at or under 0.1 after the 28-day window |
Questions
Should a reserved slot stay empty if the widget fails?
Yes, or show a fallback of the same size. web.dev advises against collapsing reserved space, since the collapse is itself a shift.
Does lazy loading cause layout shift?
Not if the lazy images have width and height. web.dev recommends dimensions on all images so space is reserved whether or not they load later.
How long until field CLS improves?
Field data covers a rolling 28-day period, so the full effect shows only after the old visits leave the window.
Sources
- web.dev, Optimize Cumulative Layout Shift, last updated February 7, 2025.
- web.dev, Cumulative Layout Shift (CLS), last updated April 12, 2023.
- web.dev, Back/forward cache, last updated October 16, 2026.
- web.dev, Optimize web fonts, last updated November 1, 2023.
- MDN Web Docs, prefers-reduced-motion, no date checked.