Fix LCP in SvelteKit
Largest Contentful Paint (LCP) is a critical Core Web Vital that measures how quickly the main content of your page becomes visible. In Svelte applications, common issues include unoptimized images, render-blocking resources, and inefficient data loading patterns that delay the largest visible element.
This guide walks through five targeted fixes for LCP in Svelte, with real code examples and before/after performance comparisons. Each step addresses a specific bottleneck in the Svelte rendering pipeline.
Expected results
Following all five steps typically produces these improvements:
Before
3.4s
LCP score (Needs Improvement) -- standard img tags, no preloading, client-side rendering delays
After
1.1s
LCP score (Good) -- optimized with enhanced:img, preloading, SSG, and minimal hydration
Step-by-step fix
Use enhanced:img for automatic image optimization
SvelteKit's enhanced:img preprocessor automatically generates responsive images in multiple formats (WebP, AVIF) and sizes at build time. It adds width and height attributes to prevent CLS, and creates srcset for responsive loading. For the LCP image, add loading="eager" and fetchpriority="high".
enhanced:img feature requires @sveltejs/enhanced-img to be installed and configured in your svelte.config.js. Without it, you lose automatic format conversion and responsive sizing.

Preload critical resources with SvelteKit load functions
SvelteKit's load functions run before the page renders, letting you preload data and critical resources. Use +page.server.ts to fetch data on the server, and add link headers for critical resources. This ensures the browser starts fetching resources before the HTML is even fully parsed.
import type { LayoutServerLoad } from './$types';
export const load: LayoutServerLoad = async ({ setHeaders }) => {
// Preload critical font via Link header
setHeaders({
'Link': [
'; rel=preload; as=font; type=font/woff2; crossorigin',
].join(', ')
});
};
Pre-render static pages for edge delivery
SvelteKit supports page-level rendering strategy configuration. For content pages that do not need server-side data at request time, enable pre-rendering to generate static HTML at build time. These pages serve from CDN edge nodes with near-zero TTFB, directly improving LCP.
// Pre-render this page at build time
export const prerender = true;
// Or in svelte.config.js for all pages:
// kit: { prerender: { entries: ['*'] } }
Minimize client-side JavaScript with Svelte's compiler
Svelte compiles components to imperative DOM operations at build time, producing smaller bundles than virtual-DOM frameworks. Further reduce JavaScript by using SvelteKit's streaming SSR, avoiding unnecessary reactive declarations in above-the-fold components, and using dynamic imports for heavy below-the-fold components.
Dashboard
{#if ChartComponent}
{:else}
{/if}
Self-host fonts with font-display swap
Download your web fonts and serve them from your own domain to eliminate the round-trip to external font services. Use font-display: swap to show fallback text immediately while fonts load. Combine with WOFF2 compression and unicode-range subsetting to minimize font file sizes.
/* Self-hosted font with swap for instant text rendering */
@font-face {
font-family: 'Inter';
src: url('/fonts/inter-var-latin.woff2') format('woff2');
font-weight: 100 900;
font-display: swap;
unicode-range: U+0000-00FF, U+0131, U+0152-0153;
}
/* Fallback with adjusted metrics */
@font-face {
font-family: 'Inter Fallback';
src: local('Arial');
size-adjust: 107.64%;
ascent-override: 90.49%;
descent-override: 22.56%;
}
:root {
--font-body: 'Inter', 'Inter Fallback', system-ui, sans-serif;
}
Quick checklist
-
LCP image uses
enhanced:imgwithloading="eager"andfetchpriority="high" -
Critical fonts preloaded via Link header in
+layout.server.ts -
Content pages use
prerender = truefor static generation -
Below-fold components lazy-loaded with dynamic
import() -
Fonts self-hosted with
font-display: swapand WOFF2 format - Deployed to edge runtime (Vercel Edge, Cloudflare Pages)
Frequently asked questions
A well-optimized SvelteKit site using pre-rendering should achieve LCP under 1.3 seconds. Svelte's compiler produces smaller JavaScript bundles than React-based frameworks, giving it a natural LCP advantage. With enhanced:img, preloaded fonts, and edge deployment, sub-second LCP is realistic for content-focused pages.
Yes. Svelte compiles components to minimal imperative DOM updates at build time, eliminating the virtual DOM diffing overhead found in React, Vue, and Angular. This means smaller JavaScript bundles (often 30-50% smaller), faster hydration, and less main thread blocking -- all of which contribute to better LCP scores.
Use SSG (prerender = true) for all pages where content does not depend on the request context. Pre-rendered pages serve from CDN edge nodes with minimal TTFB. For pages that need dynamic data, SvelteKit's streaming SSR sends the HTML shell first and streams data as it becomes available, which is the next-best option for LCP.
SvelteKit generally produces better LCP scores than Next.js due to smaller JavaScript bundles and no virtual DOM overhead. CrUX data shows Svelte-based sites have strong CWV pass rates. The tradeoff is a smaller ecosystem -- fewer third-party components and integrations compared to Next.js.
The enhanced:img preprocessor works best with local images imported from your project. For remote images (from a CMS or CDN), use a standard img tag with explicit width, height, loading='eager', and fetchpriority='high' for the LCP image. Consider using an image CDN like Cloudinary or Imgix that handles format conversion and resizing at the edge.
Google rates LCP as 'good' when it is under 2.5 seconds at the 75th percentile. For Svelte applications specifically, aim for under 2.0 seconds. Measure with field data from Chrome User Experience Report (CrUX) through PageSpeed Insights, as lab tests may not reflect real-user experience with third-party scripts and varying network conditions.
Continue learning
Fix CLS in SvelteKit
Related performance optimization for the same framework.
GuideComplete LCP Guide
Deep dive into LCP -- thresholds, measurement, and optimization strategies.
FixFix LCP in Next.js
Compare LCP fixes across different frameworks.
ToolCWV Score Explainer
Enter your scores for personalized fix recommendations.