Background performance: file weight, LCP and Core Web Vitals
Last reviewed on 28 April 2026.
A heavy hero background is one of the easiest performance regressions to ship and one of the most expensive to fix once it is live. The browser cannot paint the most visually important part of the page until the background has loaded; analytics show users abandoning slow pages before that paint completes; search engines penalise it. This page covers the working knowledge that lets you ship visually rich backgrounds without paying that cost.
Why backgrounds dominate Largest Contentful Paint
Largest Contentful Paint (LCP) is one of Google's three Core Web Vitals and measures the time from navigation start to when the largest visible element above the fold finishes painting. On a hero-heavy marketing page, the LCP element is almost always the hero — and on a hero with a full-bleed background, the background is what holds the LCP element up. If the background is a slow-loading image, LCP is slow.
The thresholds Google publishes are 2.5 seconds to be classified as "good" and 4.0 seconds to be classified as "poor", measured at the 75th percentile of real user visits. A 1.5 MB hero JPEG on a fast home connection might paint in 1.2 seconds; on a slow mobile connection it can take 6 or 7 seconds, which puts the page firmly in the "poor" bucket regardless of how clean the rest of the markup is.
File-weight budgets that work in practice
Most teams that hit Core Web Vitals reliably operate on a hero-image budget of around 200 KB at the source, with smaller variants served via srcset for narrow viewports. Above 500 KB you are almost certainly using the wrong format, the wrong resolution, or both. The file formats and resolution guide covers the format choice in depth; the rough table below is a working starting point.
| Background type | Sensible source budget | Notes |
|---|---|---|
| Hero photograph or photographic abstract | ~200 KB (WebP/AVIF) | Ship a 1× and 2× variant via srcset |
| Section background (smaller area) | ~80 KB | Often replaceable with a CSS gradient |
| Repeating texture tile | < 20 KB | Tile via background-repeat, not by exporting the full canvas |
| Geometric pattern | 1–4 KB (SVG) or pure CSS | Vector at any resolution beats raster |
The CSS-first rule
The cheapest background is the one you never download. A two- or three-stop gradient, a repeating dot pattern, a subtle vignette over a flat colour — all of these can be expressed in a few hundred bytes of CSS that ships in the same response as the HTML. The CSS background techniques reference covers the building blocks.
The defensible rule is: ship CSS unless the background is a photograph or a hand-authored raster effect that cannot be reasonably reproduced. Almost every "we needed an image because the design called for X" turns out, on inspection, to need three stacked gradients and a small SVG noise overlay.
Background images and the loading sequence
A background image declared in CSS is discovered later in the loading process than an <img> tag in HTML. The browser has to download the CSS, parse it, calculate the styles for the element, and only then queue the background image. On a slow connection that delay can add a full second to LCP for the same image. Two practical mitigations:
- Use
<link rel="preload" as="image">in the document head to tell the browser to start fetching the hero image immediately, before the CSS is parsed. - Where the design allows, render the hero image as an
<img>withfetchpriority="high"and use absolute positioning to put it behind the foreground content. This produces faster LCP than a CSS background of the same image.
<link rel="preload" as="image" href="/path/to/hero.avif" fetchpriority="high">
Lazy loading what you don't need yet
Below-the-fold backgrounds should not block the first paint. A <img loading="lazy"> attribute defers off-screen images until the user is about to scroll to them; for CSS backgrounds, the equivalent move is to apply the background image only when an ancestor element gains a class set by an IntersectionObserver. The content-visibility: auto property is also worth considering: it tells the browser it can skip rendering off-screen sections entirely until they are needed, which can cut paint time on long pages by a meaningful margin.
Animation, GPU pressure and battery
An animated background is not just a load-time problem; it keeps consuming resources for as long as the page is open. A full-screen looping conic gradient or animated mesh can pin a CPU core at 30–50% on a low-end laptop and visibly drain battery on phones. The defensive practices:
- Honour
prefers-reduced-motion. Freeze the animation when the user has asked for less motion. The accessibility guide covers the broader case. - Limit animation to transform and opacity properties. The compositor can animate these on the GPU without re-painting the layer; animating background-position or other paint-affecting properties forces a paint on every frame.
- Pause the animation when the page is hidden. The
document.visibilityStateAPI and thevisibilitychangeevent let you do this in a few lines.
Cumulative Layout Shift and backgrounds
Backgrounds rarely cause Cumulative Layout Shift (CLS) directly, but they can hide layout problems that contribute to it. A late-loading hero photograph can be replaced by a flat gradient placeholder that paints immediately and matches the dominant colour of the photograph; when the photograph arrives, the swap is invisible because the colour value is the same. Tools that auto-extract the dominant colour from an image can produce these placeholders automatically as part of a build step.
Measuring what you ship
Two tools are sufficient for almost all background-performance work. Lighthouse in the browser's dev-tools gives you a synthetic LCP figure for the page you are looking at; Real User Monitoring (RUM) via the Chrome User Experience Report or a service like web-vitals.js gives you the 75th-percentile figure across actual visits, which is the number Google ranks on. The first is fast feedback during development; the second is the truth.
A short performance checklist for backgrounds
- Hero source images under ~200 KB; section backgrounds under ~80 KB.
- WebP or AVIF for photographic backgrounds; SVG or CSS for geometry; never PNG for photographs.
- Hero image preloaded or rendered as a high-priority
<img>, not deferred behind a CSS file. - Below-the-fold backgrounds lazy-loaded.
- Animation honours
prefers-reduced-motionand pauses when the page is hidden. - LCP measured under real network conditions, not on a fast home connection.
The pages on this site that ship the visually richest hero sections do so without any background image at all — every effect on those pages is rendered with CSS, which is the simplest path to a fast page. If you hit the limits of CSS, the techniques above keep raster backgrounds within performance budgets that real users will not notice.