TroubleshootingIntermediate

Improve Largest Contentful Paint (LCP)

LCP is critical for SEO and user experience. Identify slow-loading hero images, optimize resource priorities, improve server response, and deliver fast LCP scores.

13 min read
Atatus Team
Updated March 15, 2025
6 sections
01

Understanding Largest Contentful Paint

LCP measures when the page's main content becomes visible, which determines when users perceive the page as loaded.

Largest Contentful Paint (LCP) measures the render time of the largest visible content element in the viewport—typically a hero image, large text block, or background image. Google's Core Web Vitals thresholds classify LCP under 2.5 seconds as Good, 2.5 to 4 seconds as Needs Improvement, and over 4 seconds as Poor. LCP is a direct ranking factor in Google's Page Experience algorithm, making LCP improvement both a UX priority and an SEO requirement for competitive search visibility.

The LCP element can change as the page loads—as new elements render, the browser continuously updates which is the largest. An initial placeholder image might be the first LCP candidate, replaced by a larger hero image when it loads. The final LCP time is recorded when the page finishes loading and no new larger elements appear. Understanding that LCP is the final measurement of the largest element helps explain why rendering a fast initial placeholder followed by a slow hero image does not help LCP—only the slow hero image render time is recorded.

LCP is affected by four sub-components that you can measure and optimize independently: TTFB (time from user request to first response byte), resource load delay (time from TTFB to when the browser begins loading the LCP resource), resource load time (time to download and process the LCP resource), and element render delay (time from resource load completion to LCP element render). Each sub-component requires different optimization techniques, and the dominant sub-component for a specific page determines which optimization delivers the most LCP improvement.

Different page types have different typical LCP elements. Landing pages with hero images have LCP determined by the hero image load time. Blog posts with large header text have LCP determined by text rendering, which is faster than image loading. E-commerce product pages have LCP determined by the product's main image. Understanding which element is the LCP element for each of your important page templates guides optimization efforts to the correct resource type. Use Chrome DevTools' Performance panel or the LCP Web Vitals library to identify the LCP element for each page.

02

Track LCP Across All Pages

Comprehensive LCP monitoring reveals which pages have poor scores and which users are affected.

Collect LCP measurements from real users using the PerformanceObserver API and the Web Vitals JavaScript library. These measurements reflect actual user experiences across all device types, network speeds, and geographic locations—far more representative than lab measurements. Aggregate LCP data at the 75th percentile (as Google does for Core Web Vitals) to get a metric that represents the experience of your slower users, not just the median or fastest users. A P75 LCP target of under 2.5 seconds means 75% of your page loads must achieve LCP under 2.5 seconds.

Segment LCP data by page template, device type (mobile vs desktop), effective connection type (4G vs 3G), and geographic region to identify where poor LCP is concentrated. Mobile users on slower connections in regions far from your origin servers will experience the worst LCP scores. A P75 LCP of 2.3 seconds for desktop users may accompany a P75 LCP of 5.2 seconds for mobile users on 3G—the aggregate metric would show a passing grade while a significant user segment has a failing score.

Track LCP trends over time to detect gradual degradation from new features, increased image sizes, added third-party scripts, and other changes that individually appear minor but cumulatively degrade LCP. Set up weekly LCP reports by page template and alert on LCP scores that exceed your thresholds. Deployment annotations on LCP trend charts make it easy to correlate LCP degradation with specific releases, enabling rapid rollback or targeted fixes when a new feature introduces LCP regression.

Compare LCP against competitors using field data from the Chrome User Experience Report (CrUX), which contains real user LCP measurements for millions of URLs accessible to the public. The Google PageSpeed Insights API provides both lab measurements and CrUX field data for any URL. Understanding whether your LCP is better or worse than competitor pages in the same industry category provides context for prioritizing LCP investment and demonstrates the competitive importance of LCP optimization to product stakeholders.

03

Optimize LCP Element Loading

The LCP element is usually an image—optimizing its discovery and loading is the highest-impact LCP improvement.

Preloading the LCP image is the single highest-impact LCP optimization for image-heavy pages. A preload link tag in the document head tells the browser to begin fetching the LCP image at the highest priority, as early as possible—even before the browser has parsed far enough into the HTML to discover the img tag. Without preloading, the browser discovers the LCP image only after parsing the HTML to the img element, potentially 300 to 500ms into page loading. Adding a preload tag reduces LCP by the full delay between page start and image discovery.

Modern image formats significantly reduce LCP image file size and therefore download time. WebP provides approximately 30% smaller file sizes than JPEG at equivalent visual quality, while AVIF provides 50% smaller sizes than JPEG. Smaller files download faster on all connection types—a 500KB hero image at WebP size (350KB) downloads 30% faster than the JPEG version. Use the HTML picture element to serve WebP/AVIF to browsers that support them while falling back to JPEG for older browsers. Image optimization CDN services like Cloudinary, Imgix, and Fastly's image optimizer handle format conversion and serving automatically.

Responsive images using the srcset attribute serve appropriately sized images based on screen width and device pixel ratio, preventing mobile devices from downloading full-resolution desktop images. A hero image at its natural 2,000px width and 400KB file size is unnecessarily large for a 375px wide phone screen—the phone needs only a 750px wide image (for 2x retina displays) at approximately 80KB. The srcset attribute allows the browser to choose the optimal image variant, reducing LCP image download time by 70 to 80% for mobile users.

Eliminating render-blocking resources before the LCP element reduces the time between page navigation and when the browser can begin rendering the LCP element. CSS files in the document head must be downloaded and parsed before any rendering occurs. Render-blocking JavaScript scripts delay the parser. Critical CSS inlining—embedding the minimal CSS needed for above-the-fold rendering directly in the HTML—eliminates one blocking resource entirely. Auditing and removing render-blocking resources that are not needed for the LCP element's rendering reduces the resource load delay LCP sub-component.

04

Improve Server Response and CDN Delivery

LCP improvements from server and network optimizations have the widest user impact.

TTFB directly contributes to LCP—no LCP element can render before the server responds. A TTFB of 1,500ms means LCP cannot be below 1,500ms regardless of any client-side optimizations. Reduce TTFB through CDN caching for HTML pages (serving from edge rather than origin eliminates 100 to 300ms of network transit), database query optimization (reducing server processing time by fixing N+1 queries and adding indexes), and response caching (eliminating repeated processing for identical page requests). Each 100ms reduction in TTFB improves LCP by 100ms.

CDN delivery of the LCP image resource reduces image download time for users in regions distant from your origin. An image served from an origin server in US East takes 50ms to reach a US West user and 150ms to reach a European user, while a CDN-cached image served from nearby edge nodes takes 5-10ms for both. CDN image delivery requires correct Cache-Control headers on image responses (max-age of at least 1 year for versioned assets), and CDN support for image format conversion and compression to deliver WebP and AVIF from a single source JPEG.

Early hints (103 status code) allow the server to inform the browser about the LCP image before sending the full HTML response. When the server starts processing a request, it knows which hero image will be on the page before database queries complete—it can immediately send a 103 Early Hints response with a Link: preload header for the LCP image. The browser begins fetching the image while the server continues generating the full HTML response. This parallelism can reduce LCP by 200 to 400ms for pages with server-side processing time above 200ms.

Streaming HTML responses with React Suspense or PHP output buffering can deliver the document head containing the LCP image preload tag before server-side data queries complete. For pages that require database queries for body content but have a static header section, streaming the header immediately allows the browser to discover and preload the LCP image while server queries are still running. The total time for the browser to begin loading the LCP image is reduced by the portion of server processing time that runs after the LCP element's position in the HTML document.

05

Fix Common LCP Antipatterns

Several common implementation patterns systematically delay LCP without obvious benefit.

Lazy loading the LCP image is one of the most common LCP antipatterns. The loading='lazy' attribute causes the browser to defer loading an image until it is near the viewport, but the LCP element is by definition in the initial viewport and should load as early as possible. Adding loading='lazy' to a hero image tells the browser not to load it until it enters the viewport—which is immediately, but only after the browser has parsed the img element and calculated the element's position. Remove loading='lazy' from LCP images and ensure that lazy loading is only applied to below-the-fold images.

Background images in CSS are discovered later than inline images in HTML because the browser must download and parse the CSS file before it discovers the background image URL. A hero section with background-image: url(...) in a CSS file has LCP delayed by the CSS download and parse time plus the additional round trip to fetch the background image. Convert CSS background images that serve as LCP elements to HTML img tags with appropriate position and styling, allowing the browser to discover the image from the HTML parser rather than waiting for CSS parsing.

Client-side rendering (CSR) without server-side rendering delays LCP because the browser must download, parse, and execute JavaScript before any page content renders. For a React CSR app, the LCP cannot occur until React has loaded and rendered the component tree—adding 500ms to 2,000ms of JavaScript execution time to the critical path. Server-Side Rendering (SSR) or Static Site Generation (SSG) with Next.js, Gatsby, or similar frameworks delivers HTML content immediately, allowing LCP to occur as soon as the LCP element's resource loads, without waiting for JavaScript execution.

Oversized images that are not optimized for their display dimensions waste bandwidth and delay LCP. An image displayed at 800px width served as a 3,000px wide file is 10 to 15 times larger than necessary. Use your browser's DevTools network panel to check the 'Resource Size' versus the 'Rendered Size' for each image—a large gap indicates over-serving. Implement image transformation at upload time (resizing to multiple standard dimensions), at serve time (CDN image optimization with width parameters), or using HTML srcset to serve appropriately sized variants based on viewport dimensions.

06

Monitor LCP in Real User and Lab Environments

Both real user and synthetic monitoring are necessary for comprehensive LCP management.

Real User Monitoring (RUM) captures LCP from actual user devices and network conditions across your complete user base. The Web Vitals JavaScript library reports LCP (along with FID and CLS) through a single addMetric callback, making RUM implementation straightforward. Send LCP data to your analytics or APM platform with page URL, user agent, effective connection type, and geographic country as attributes. This segmented data allows you to prioritize LCP improvements for the user segments with the worst scores rather than optimizing for the best-case conditions that synthetic tools measure.

Lighthouse in Google PageSpeed Insights and Chrome DevTools provides lab-based LCP measurements with detailed recommendations. Lighthouse simulates a mid-range mobile device on a throttled 3G connection by default, representing a challenging but representative user scenario. The Lighthouse report identifies the LCP element, the LCP breakdown by sub-component, and specific recommendations with estimated impact. Use Lighthouse recommendations as a starting point for optimization, but validate improvements with RUM data to confirm they improve real user LCP across all device types.

WebPageTest provides detailed LCP filmstrip views that show exactly when the LCP element renders relative to other page loading events. The filmstrip visualization makes it immediately apparent whether LCP is delayed by slow TTFB, late image discovery, slow image download, or render-blocking resources. WebPageTest also supports testing from multiple geographic locations and network speeds simultaneously, providing the multi-location LCP data needed to diagnose whether LCP problems are universal or geography-specific.

Set up Lighthouse CI or similar automated synthetic testing in your CI/CD pipeline to enforce LCP thresholds for every deployment. Configure the pipeline to run Lighthouse against your critical pages after deployment to a staging environment and fail the deployment if LCP exceeds your threshold. This creates a performance gate that prevents LCP regressions from reaching production and provides objective pass/fail data for each pull request. Combine CI/CD performance gates with production RUM monitoring for defense-in-depth against LCP degradation.

Key Takeaways

  • Preloading the LCP image with a link rel=preload tag in the document head is the single highest-impact LCP optimization for most pages—it eliminates 200-500ms of image discovery delay
  • Never add loading='lazy' to the LCP image—this is an antipattern that explicitly tells the browser to delay loading the element that determines the LCP score
  • WebP and AVIF reduce LCP image file size by 30-50% compared to JPEG, directly reducing download time—use picture element for cross-browser compatibility
  • TTFB directly limits LCP—no LCP element can render before the server responds, making TTFB reduction the highest-impact server-side LCP optimization
  • Background images in CSS files are discovered later than HTML img tags because CSS must be downloaded and parsed first—convert LCP elements from CSS backgrounds to HTML img tags
  • Client-side rendering (CSR) SPA frameworks delay LCP by requiring JavaScript execution before any content renders—SSR or SSG delivers HTML content that enables LCP without JavaScript execution
Get started today

Monitor your applications with Atatus

Put the concepts from this guide into practice. Set up full-stack observability in minutes with no credit card required.

No credit card required14-day free trialSetup in minutes

Related guides