# Speed Index: what it is and how to improve it

**Audit ID:** `speed-index` · **Category:** Performance

<!--QA-->
> **Quick answer:** Speed Index measures how quickly the visible parts of a page fill in during load, computed from a filmstrip of the loading viewport. Good is under 3.4 seconds on mobile. Improve it by eliminating render-blocking resources, adding font-display so text renders immediately, and loading above-the-fold images early.
<!--/QA-->

Speed Index measures how quickly the visible parts of your page fill in during load. Unlike metrics that mark a single moment, it scores the whole visual loading experience: a page that paints most of its content early gets a good Speed Index even if the last widget takes a while.

## TL;DR

- **What:** How quickly page content is visually complete, computed from a filmstrip of the load.
- **Target:** Under 3.4 seconds on the throttled mobile profile.
- **Top three fixes:** eliminate render-blocking resources, show text immediately with `font-display`, get above-the-fold images in early.

## What is Speed Index in Lighthouse?

During a Lighthouse run, the page load is captured as a series of video frames. Each frame is compared to the final rendered page to compute visual completeness over time. Speed Index is the weighted average of that curve, expressed in seconds: the faster the visible viewport fills in, the lower (better) the number.

The key property: it rewards progressive rendering. Two pages can both finish loading in 5 seconds, but the one that shows 90% of its content at 1 second scores far better than the one that stays blank until 4.5 seconds.

## What is a good Speed Index score?

| Range (mobile) | Verdict |
|---|---|
| ≤ 3.4 s | Good |
| 3.4 – 5.8 s | Needs improvement |
| > 5.8 s | Poor |

In our [study of 269 Shopify stores](/reports/shopify-lighthouse-performance-2026), 84% failed this audit, making it one of the most commonly failed checks on real ecommerce sites.

## How is Speed Index different from FCP and LCP?

They answer different questions about the same load:

- **[First Contentful Paint](/audits/first-contentful-paint)** marks one moment: when the *first* text or image appears.
- **[Largest Contentful Paint](/audits/largest-contentful-paint)** marks one moment: when the *biggest* element renders.
- **Speed Index** integrates the *whole* visual timeline: how complete the viewport looked at every moment in between.

That is why Speed Index catches problems the moment-metrics miss. A page can have a fast FCP (one headline pops in early) and a decent LCP, yet still feel slow because everything between the headline and the hero trickles in over 6 seconds. Speed Index is the metric that punishes that trickle. In practice you rarely optimize Speed Index directly: you fix the causes below and it follows.

## What causes a high Speed Index?

1. **Render-blocking CSS and JavaScript**: nothing paints until the blocking resources in `<head>` finish. This is the most common cause and the biggest lever.
2. **Invisible text during font loading**: web fonts without [`font-display`](/audits/font-display) hold large text areas empty while the font downloads.
3. **Late-arriving above-the-fold images**: heroes and product images that are oversized, unoptimized, or lazy-loaded when they should not be.
4. **Client-side rendering**: single-page apps that ship a blank shell and paint everything after the JavaScript bundle executes.
5. **Heavy main-thread work**: long tasks delay paint work between frames; see [Total Blocking Time](/audits/total-blocking-time).

## How do I improve Speed Index?

Work down the causes in order:

### 1. Unblock the first paint

Inline critical CSS, defer non-critical stylesheets, and add `defer`/`async` to scripts. The full playbook is in [eliminate render-blocking resources](/audits/render-blocking-resources): every millisecond saved there moves Speed Index almost one for one.

### 2. Make text render immediately

Add `font-display: swap` (or `optional`) to every `@font-face`, and `&display=swap` to Google Fonts URLs. Text is usually most of the visible viewport, so invisible text destroys visual completeness. Details on the [font-display page](/audits/font-display).

### 3. Get above-the-fold images in early

- Never lazy-load the hero or anything above the fold; add `loading="lazy"` only below it.
- Preload the LCP image: `<link rel="preload" as="image" href="/hero.avif">`.
- Serve [modern formats](/audits/modern-image-formats) at the right dimensions so the bytes arrive fast.

### 4. Render meaningful HTML from the server

If the page is a client-rendered SPA, move the above-the-fold content to SSR or static generation. A server-rendered shell with real content can cut Speed Index in half on its own, and it is the same change that makes the page readable to AI crawlers that do not execute JavaScript.

### 5. Show structure while data loads

Where content genuinely must load late, render skeletons or placeholder blocks with the final dimensions. Visually complete regions count, and reserved space also protects your [CLS](/audits/cumulative-layout-shift).

## What are common Speed Index mistakes?

- **Chasing Speed Index directly.** It is a derived metric. Fix render-blocking, fonts, and images; the number follows.
- **Lazy-loading everything.** `loading="lazy"` on above-the-fold images makes Speed Index and LCP worse.
- **A fast FCP hiding a slow fill.** One early headline does not mean the page renders progressively; check the filmstrip.
- **Testing only on desktop.** The mobile throttled profile is where Speed Index fails; it is also the profile Google's tooling reports.

## How do I verify Speed Index improved?

1. Re-run Lighthouse (mobile) and compare the Speed Index value, not just the score.
2. Open the filmstrip view in the Lighthouse report or DevTools Performance panel: the frames should fill in earlier and more completely.
3. Confirm the fixes did not regress neighbors: [FCP](/audits/first-contentful-paint), [LCP](/audits/largest-contentful-paint), and [CLS](/audits/cumulative-layout-shift) should improve or hold.

## Related audits

- [Eliminate render-blocking resources](/audits/render-blocking-resources), the biggest Speed Index lever
- [font-display](/audits/font-display), invisible text is invisible progress
- [First Contentful Paint (FCP)](/audits/first-contentful-paint), the start of the visual timeline
- [Largest Contentful Paint (LCP)](/audits/largest-contentful-paint), the biggest single moment in it

---

Audit your URL at https://lighthouse-md.com.
