From harness-claude
Measures and optimizes Largest Contentful Paint (LCP) by decomposing into TTFB, resource load delay, load time, and render delay phases with targeted fixes like preload links and TTFB reduction. For Lighthouse >2.5s or slow hero images.
npx claudepluginhub intense-visions/harness-engineering --plugin harness-claudeThis skill uses the workspace's default tool permissions.
> Measure and optimize LCP — the time until the largest visible content element renders — by decomposing it into 4 sub-parts (TTFB, resource load delay, resource load time, element render delay) and targeting each with specific strategies.
Debugs and optimizes Largest Contentful Paint (LCP) using Chrome DevTools traces and insights, analyzing TTFB, resource load delays/durations, and render delays for Core Web Vitals.
Conducts web performance audits with Core Web Vitals (LCP, FID, CLS, INP), Lighthouse automation, bottleneck identification, and optimization recommendations for page load times and UX issues.
Guides optimization of Core Web Vitals (LCP, INP, CLS) for improved page experience and search rankings. Covers diagnostics, thresholds, and fixes for loading, responsiveness, and visual stability.
Share bugs, ideas, or general feedback.
Measure and optimize LCP — the time until the largest visible content element renders — by decomposing it into 4 sub-parts (TTFB, resource load delay, resource load time, element render delay) and targeting each with specific strategies.
fetchpriority or <link rel="preload"> for critical resourcesIdentify the LCP element. In Chrome DevTools, run a Lighthouse audit or use the Performance panel. The LCP element is highlighted in the Performance Insights panel. Common LCP elements: hero images, background images via CSS, large text blocks, video poster images. The LCP candidate can change during load — the browser reports the largest element at the time each candidate is rendered.
Decompose LCP into 4 sub-parts. Every millisecond of LCP belongs to one of these phases:
Optimize TTFB. Reduce server response time:
<head> earlyEliminate resource load delay. Ensure the browser discovers the LCP resource as early as possible:
<!-- Preload the LCP image so the browser fetches it immediately -->
<link rel="preload" href="/hero.webp" as="image" fetchpriority="high" />
<!-- For responsive images, preload with srcset -->
<link
rel="preload"
href="/hero-800.webp"
as="image"
imagesrcset="/hero-400.webp 400w, /hero-800.webp 800w"
imagesizes="100vw"
/>
Reduce resource load time. Optimize the LCP resource itself:
Minimize element render delay. Remove bottlenecks between resource load and render:
Never lazy-load the LCP image. loading="lazy" on the LCP image delays its discovery and loading:
<!-- BAD — hero image waits for intersection observer, delaying LCP -->
<img src="/hero.webp" loading="lazy" alt="Hero" />
<!-- GOOD — hero image loads immediately with high priority -->
<img src="/hero.webp" fetchpriority="high" alt="Hero" />
| Rating | LCP (p75) | Description |
|---|---|---|
| Good | <= 2.5s | Users perceive load as fast |
| Needs improvement | <= 4.0s | Noticeable delay |
| Poor | > 4.0s | Users likely to abandon |
These thresholds are at the 75th percentile of page loads — meaning 75% of users should see LCP under 2.5s for a "good" rating.
Vodafone improved LCP by 31%, from 4.2s to 2.9s. The sub-part breakdown before optimization:
Fixes applied:
<link rel="preload" href="/hero.webp" as="image" fetchpriority="high"> in <head> — resource load delay dropped from 1,800ms to 300msThe Economic Times reduced LCP from 7s to 2.5s by switching from client-side rendering (CSR) to server-side rendering (SSR) with streamed HTML. Under CSR, LCP required: HTML download (200ms) + JS bundle download (1.5s) + JS parse and execute (2s) + API fetch (1.5s) + render (500ms) + image load (1.3s). Under SSR, the HTML already contains the rendered content, so LCP required: HTML download with streamed flush (200ms) + image preloaded in parallel (800ms) + render (200ms).
The LCP API considers these element types:
<img> elements (including <img> inside <picture>)<image> inside <svg><video> poster images (the poster attribute image, not the video itself)background-image loaded via CSS url()Elements with opacity: 0, visibility: hidden, or zero-size are excluded.
const observer = new PerformanceObserver((list) => {
const entries = list.getEntries();
const lastEntry = entries[entries.length - 1];
console.log('LCP:', lastEntry.startTime, 'Element:', lastEntry.element);
console.log('URL:', lastEntry.url); // resource URL for images
console.log('Size:', lastEntry.size); // area in pixels
});
observer.observe({ type: 'largest-contentful-paint', buffered: true });
Lazy-loading the LCP image. loading="lazy" defers image loading until it enters the viewport, detected by an IntersectionObserver. For the LCP image (which is by definition visible in the viewport), this adds unnecessary delay — the image is not fetched until after layout determines it is visible, instead of immediately on HTML parse.
LCP element loaded via JavaScript. Client-side rendering means the LCP element does not exist in the initial HTML. The browser must download JavaScript, parse it, execute it, potentially fetch data from an API, then render the element. This adds 2-5 seconds to LCP compared to server-side rendering.
Excessive redirect chains before the document. Each HTTP redirect adds a full roundtrip (300-600ms). A chain of marketing-tracking redirect to www redirect to HTTPS redirect adds 1-2 seconds before the HTML even begins downloading.
Unoptimized hero images. A 6MB PNG hero image when a 200KB WebP would produce identical visual quality at the viewport size. Always serve correctly-sized, modern-format images. Use <picture> with <source> for format fallbacks.
Render-blocking third-party scripts. Synchronous third-party scripts (analytics, A/B testing, consent managers) in <head> delay rendering of the LCP element. Load them with defer or async, or load them after LCP fires.