Fix Page Redirects for Better LCP

Eliminate redirect chains that delay LCP. Learn to identify and fix 301/302 redirects, canonical URL issues, and trailing slash mismatches.
Harlan WiltonHarlan Wilton6 min read Published

Every redirect adds a full network round-trip before your page begins loading. A single redirect costs 100-500ms. A chain of 3 redirects? That's potentially 1.5 seconds wasted before the browser receives a single byte of HTML.

LCPLargest Contentful Paint CWV
25% weight
Good ≤2.5sPoor >4.0s

What's the Problem?

Redirects force the browser to make additional HTTP requests before reaching the final destination. Lighthouse flags this as "Avoid multiple page redirects" and calculates the cumulative delay. Each redirect in the chain introduces latency from DNS lookup, TCP connection, TLS handshake, and waiting for the server response.

The damage compounds quickly. A user clicks a link to http://example.com. The server responds with a 301 redirect to https://example.com. Then another 301 to https://www.example.com. Then a 302 to https://www.example.com/. Three redirects, three round-trips, potentially 900ms+ of pure waste before the browser even begins downloading HTML.

Common redirect causes include: HTTP to HTTPS upgrades, www to non-www normalization (or vice versa), trailing slash enforcement, mobile redirects, marketing campaign tracking, and legacy URL migrations. Each is legitimate on its own, but combined they create performance-killing chains that directly inflate LCP.

How to Identify This Issue

Chrome DevTools

  1. Open DevTools (F12) and navigate to the Network tab
  2. Reload the page and look at the first request
  3. If it shows a 301 or 302 status, click it and check the "Location" response header
  4. Follow the chain until you see a 200 response
  5. Count the redirects—each one costs time

Command Line

curl -sIL https://example.com 2>&1 | grep -E "^(HTTP|Location)"

curl -w "Redirect: %{redirect_url}\nTime: %{time_total}s\n" -sIL -o /dev/null https://example.com

curl -sIL -o /dev/null -w "%{redirect_url}\n" https://example.com | wc -l

Lighthouse Indicators

The "Avoid multiple page redirects" audit appears under Opportunities when redirects are detected. Lighthouse shows:

  • Each URL in the redirect chain
  • Time wasted per redirect in milliseconds
  • Total potential savings for LCP and FCP

A passing score means the final URL was reached directly without redirects.

The Fix

The most effective fix is eliminating redirects at the source—update all internal links, sitemaps, and canonical tags to point to the final destination URL.

<!-- Before: causes redirect chain -->
<a href="http://example.com/products">Products</a>
<link rel="canonical" href="http://www.example.com/products">

<!-- After: direct link to final URL -->
<a href="https://example.com/products/">Products</a>
<link rel="canonical" href="https://example.com/products/">

Update your sitemap:

<!-- Before -->
<url>
  <loc>http://example.com/page</loc>
</url>

<!-- After -->
<url>
  <loc>https://example.com/page/</loc>
</url>

Audit all external links pointing to your site (backlinks, social profiles, email signatures) and update where possible.

Secondary: Server-Side Redirect Consolidation

When redirects are necessary, combine multiple rules into a single redirect to the final destination.

server {
    listen 80;
    listen 443 ssl;
    server_name example.com www.example.com;

    # Redirect everything to canonical URL in one hop
    if ($scheme != "https") {
        return 301 https://example.com$request_uri;
    }
    if ($host = "www.example.com") {
        return 301 https://example.com$request_uri;
    }
}
RewriteEngine On

RewriteCond %{HTTPS} off [OR]
RewriteCond %{HTTP_HOST} ^www\. [NC]
RewriteRule ^(.*)$ https://example.com/$1/ [R=301,L]

For edge/CDN deployments:

// Cloudflare Workers: Single redirect
export default {
  async fetch(request) {
    const url = new URL(request.url)

    // Build canonical URL
    let redirect = false
    if (url.protocol === 'http:') {
      url.protocol = 'https:'
      redirect = true
    }
    if (url.hostname.startsWith('www.')) {
      url.hostname = url.hostname.slice(4)
      redirect = true
    }
    if (!url.pathname.endsWith('/') && !url.pathname.includes('.')) {
      url.pathname += '/'
      redirect = true
    }

    if (redirect) {
      return Response.redirect(url.toString(), 301)
    }

    return fetch(request)
  }
}

Tertiary: 301 vs 302 Redirect Strategy

Use 301 (permanent) redirects for URLs that have permanently moved. Use 302 (temporary) only for genuinely temporary situations.

# 301 for permanent moves - browsers cache these
location /old-page {
    return 301 /new-page/;
}

# 302 only for temporary situations (A/B tests, maintenance)
location /promo {
    return 302 /current-sale/;
}

301 redirects allow browsers to cache the redirect, so repeat visitors skip the round-trip entirely. 302 redirects are re-checked every time.

Bonus: Preconnect to Redirect Destinations

If redirects are unavoidable (third-party services, OAuth flows), preconnect to the destination domain:

<head>
  <!-- Preconnect to OAuth provider -->
  <link rel="preconnect" href="https://auth.provider.com">

  <!-- DNS prefetch as fallback -->
  <link rel="dns-prefetch" href="https://auth.provider.com">
</head>

Why This Works

Each redirect eliminated removes a complete network round-trip from the critical path. Without redirects, the browser's first request returns the actual HTML document instead of an instruction to request another URL. The time savings are cumulative—eliminating a chain of 3 redirects at 300ms each saves 900ms directly off LCP. Additionally, 301 redirects get cached by browsers, meaning returning visitors experience the improvement immediately without any server contact.

Framework-Specific Solutions

Next.js: Configure redirects in next.config.js to consolidate at the edge. Use trailingSlash config to enforce consistency. Deploy to Vercel for automatic HTTPS and redirect optimization.
// next.config.js
module.exports = {
  trailingSlash: true,
  async redirects() {
    return [
      {
        source: '/old-path',
        destination: '/new-path/',
        permanent: true,
      },
    ]
  },
}
Nuxt: Use routeRules for server-side redirects. Configure trailing slash behavior globally. Enable prerender for static routes to avoid redirect processing entirely.
// nuxt.config.ts
export default defineNuxtConfig({
  routeRules: {
    '/old-path': { redirect: '/new-path/' },
  },
  nitro: {
    prerender: {
      crawlLinks: true,
    },
  },
})

Verify the Fix

After implementing changes:

  1. Run the curl command to confirm no redirects occur
  2. Check DevTools Network tab—first request should return 200, not 301/302
  3. Run Lighthouse and verify "Avoid multiple page redirects" passes
  4. Test both www and non-www, HTTP and HTTPS, with and without trailing slashes
  5. Verify canonical URLs match the final destination
for url in "http://example.com" "https://example.com" "http://www.example.com" "https://www.example.com"; do
  echo "Testing: $url"
  curl -sIL "$url" | grep -E "^(HTTP|Location)"
  echo "---"
done

Expected improvement: Eliminating a typical 2-redirect chain saves 200-600ms on LCP. For mobile users on slower networks, savings can exceed 1 second.

Common Mistakes

Redirect loops: Misconfigured rules can create infinite redirect loops (A redirects to B, B redirects to A). Always test the full chain before deploying. Use curl -L --max-redirs 10 to catch loops.

Inconsistent internal links: Fixing server redirects but leaving old URLs in internal links still causes redirects. Audit your entire codebase, CMS content, and external properties. Use site-wide search-replace tools.

Forgetting trailing slash consistency: Mixing /page and /page/ creates redirects. Pick one convention and enforce it everywhere—server config, links, canonical tags, and sitemaps.

Redirects often compound other LCP problems:

Test Your Entire Site

Redirect issues often hide in forgotten corners of your site—old marketing campaign URLs, migrated pages, legacy mobile redirects. A single page audit won't catch redirect chains that only affect specific routes or user agents.

Scan Your Site with Unlighthouse