PERFORMANCEWEB DEVELOPMENTCORE WEB VITALS

How to Improve Website Performance in 2025: Complete Guide

BY VLADISLAV GERASIMCHUK, FOUNDER OF ROASTWEB.COM AND AI PLATFORMS EXPERT12 MIN READ
UPDATED: DEC 28, 2025
How to Improve Website Performance in 2025: Complete Guide

How to Improve Website Performance in 2025: Complete Guide

Page speed isn't just about user experience anymore. It's a direct Google ranking factor. Slow sites lose rankings, traffic, and revenue.

This guide covers everything you need to know about website performance optimization in 2025, from Core Web Vitals to framework-specific techniques.

Why Performance Matters in 2025

Why Performance Matters in 2025

The numbers don't lie:

  • 53% of mobile users abandon sites that take longer than 3 seconds to load (Google)
  • 1-second delay in page load time reduces conversions by 7% (Akamai)
  • Core Web Vitals are now direct ranking factors in Google's algorithm
  • Page speed affects bounce rate, time on site, and ultimately revenue

Amazon found that every 100ms of latency costs them 1% in sales. For a company doing billions in revenue, that's massive.

The message is clear: Fast sites win. Slow sites lose.

Understanding Core Web Vitals

Understanding Core Web Vitals

Google measures user experience through three key metrics:

1. LCP (Largest Contentful Paint)

What it measures: How long it takes for your main content to load

Targets:

  • ✅ Good: <2.5 seconds
  • ⚠️ Needs Improvement: 2.5-4 seconds
  • ❌ Poor: >4 seconds

What counts as LCP:

  • Large images
  • Video thumbnails
  • Background images (CSS)
  • Block-level text elements

Common causes of slow LCP:

  • Unoptimized images
  • Slow server response time
  • Render-blocking JavaScript and CSS
  • Client-side rendering (everything loads via JS)

2. INP (Interaction to Next Paint)

What it measures: How quickly your site responds to user interactions (replaces FID in 2024)

Targets:

  • ✅ Good: <200ms
  • ⚠️ Needs Improvement: 200-500ms
  • ❌ Poor: >500ms

What counts as interactions:

  • Clicks
  • Taps
  • Keyboard input

Common causes of poor INP:

  • Heavy JavaScript execution
  • Long-running tasks blocking the main thread
  • No code splitting (loading everything at once)

3. CLS (Cumulative Layout Shift)

What it measures: How much your layout shifts unexpectedly during load

Targets:

  • ✅ Good: <0.1
  • ⚠️ Needs Improvement: 0.1-0.25
  • ❌ Poor: >0.25

Common causes of CLS:

  • Images without dimensions
  • Ads/embeds without reserved space
  • Fonts causing FOUT (Flash of Unstyled Text)
  • Dynamic content injected above existing content
Top 10 Performance Optimization Techniques

Top 10 Performance Optimization Techniques

1. Image Optimization

Images account for 50-70% of page weight on average. Optimize them, and you'll see dramatic improvements.

Use Next-Gen Formats

WebP is 25-35% smaller than JPEG with the same quality. AVIF is even better (50% smaller) but has less browser support.

```html <picture> <source srcset="image.avif" type="image/avif"> <source srcset="image.webp" type="image/webp"> <img src="image.jpg" alt="Fallback for old browsers"> </picture> ```

Compress Images

Tools:

  • Squoosh (browser-based)
  • ImageOptim (Mac)
  • TinyPNG (online)

Command line: ```bash

Convert to WebP with 80% quality

cwebp -q 80 input.jpg -o output.webp ```

Use Responsive Images

Serve different image sizes for different screen sizes:

```html <img srcset=" small.jpg 400w, medium.jpg 800w, large.jpg 1200w " sizes="(max-width: 400px) 400px, (max-width: 800px) 800px, 1200px" src="medium.jpg" alt="Responsive image"

```

Lazy Load Images

Don't load images until they're about to enter the viewport:

```html <img src="image.jpg" alt="Lazy loaded" loading="lazy"> ```

Next.js Example: ```jsx import Image from 'next/image';

<Image src="/hero.jpg" alt="Hero image" width={1200} height={630} priority // For above-the-fold images />

<Image src="/below-fold.jpg" alt="Below fold" width={800} height={600} loading="lazy" // Default behavior /> ```

2. Code Splitting & Lazy Loading

Don't make users download code they don't need.

JavaScript Code Splitting

Webpack (automatic): ```javascript // Dynamic import import('./heavy-module').then(module => { module.doSomething(); }); ```

Next.js: ```jsx import dynamic from 'next/dynamic';

// Only loads when component is rendered const HeavyChart = dynamic(() => import('./HeavyChart'), { loading: () => <p>Loading chart...</p>, ssr: false // Skip server-side rendering });

export default function Dashboard() { return <HeavyChart />; } ```

React.lazy: ```jsx import { lazy, Suspense } from 'react';

const Modal = lazy(() => import('./Modal'));

function App() { return ( <Suspense fallback={<div>Loading...</div>}> <Modal /> </Suspense> ); } ```

3. Server-Side Rendering (SSR)

Render HTML on the server instead of the client.

Benefits:

  • Faster Time to First Byte (TTFB)
  • Faster Largest Contentful Paint (LCP)
  • Better SEO (crawlers see content immediately)

Next.js Server Components: ```jsx // This runs on the server, sends HTML to client export default async function Page() { const data = await fetch('https://api.example.com/data'); const json = await data.json();

return <div>{json.title}</div>; } ```

When to avoid SSR:

  • Highly interactive applications (dashboards, real-time apps)
  • User-specific content that can't be cached
  • Apps behind authentication

4. CDN (Content Delivery Network)

Serve static files from servers close to your users.

Popular CDNs:

  • Cloudflare (free tier available, great DDoS protection)
  • Fastly (advanced caching rules)
  • AWS CloudFront (integrates with AWS ecosystem)
  • Vercel Edge Network (automatic for Next.js on Vercel)

What to cache:

  • Images
  • CSS and JavaScript files
  • Fonts
  • Videos

Example Cloudflare setup:

  1. Point your domain's DNS to Cloudflare
  2. Enable "Auto Minify" for HTML, CSS, JS
  3. Enable "Brotli" compression
  4. Set cache rules (Browser Cache TTL: 4 hours+)

5. Minification & Compression

Remove unnecessary bytes from your code.

Minify CSS and JavaScript

Before (10KB): ```javascript function calculateTotal(items) { let total = 0; for (let i = 0; i < items.length; i++) { total += items[i].price; } return total; } ```

After (3KB): ```javascript function c(i){let t=0;for(let e=0;e<i.length;e++)t+=i[e].price;return t} ```

Build tools do this automatically:

  • Vite (built-in)
  • Webpack (UglifyJS, Terser)
  • Next.js (`swcMinify: true`)

Enable Gzip/Brotli Compression

Compress text files before sending them to users.

Nginx config: ```nginx gzip on; gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript; gzip_comp_level 6;

Brotli (even better compression)

brotli on; brotli_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript; ```

Results:

  • Uncompressed HTML: 100KB
  • Gzip: 25KB (75% reduction)
  • Brotli: 20KB (80% reduction)

6. Caching Strategies

Store resources so they don't need to be downloaded again.

Browser Caching

Set HTTP cache headers:

```nginx

Cache static assets for 1 year

location ~* .(jpg|jpeg|png|gif|ico|css|js|woff2)$ { expires 1y; add_header Cache-Control "public, immutable"; }

Don't cache HTML (always check for updates)

location ~* .html$ { expires -1; add_header Cache-Control "no-cache, must-revalidate"; } ```

Service Worker Caching

Cache assets in the browser for offline use:

```javascript // service-worker.js self.addEventListener('install', event => { event.waitUntil( caches.open('v1').then(cache => { return cache.addAll([ '/', '/styles.css', '/script.js', '/logo.png' ]); }) ); });

self.addEventListener('fetch', event => { event.respondWith( caches.match(event.request).then(response => { return response || fetch(event.request); }) ); }); ```

7. Reduce Third-Party Scripts

Third-party scripts are the #1 cause of slow sites.

Common culprits:

  • Google Analytics
  • Facebook Pixel
  • Google Ads
  • Chat widgets (Intercom, Drift)
  • Social media embeds

How to optimize:

Defer non-critical scripts

```html

<script src="analytics.js" defer></script>

```

Use facades for embeds

Instead of loading YouTube embed (500KB+), show a thumbnail and load the player only when clicked:

```jsx import { useState } from 'react';

function YouTubeEmbed({ videoId }) { const [showPlayer, setShowPlayer] = useState(false);

if (!showPlayer) { return ( <div onClick={() => setShowPlayer(true)} style={{ cursor: 'pointer' }}> <img src={`https://img.youtube.com/vi/${videoId}/hqdefault.jpg`} alt="Video thumbnail" /> <button>Play</button> </div> ); }

return <iframe src={`https://www.youtube.com/embed/${videoId}?autoplay=1`} />; } ```

8. Optimize Web Fonts

Fonts can block rendering for 2-3 seconds if not optimized.

Use font-display: swap

Render text immediately with a fallback font while web font loads:

```css @font-face { font-family: 'CustomFont'; src: url('/fonts/custom.woff2') format('woff2'); font-display: swap; /* Show fallback immediately */ } ```

Preload critical fonts

```html

<link rel="preload" href="/fonts/custom.woff2" as="font" type="font/woff2" crossorigin> \`\`\`

Subset fonts

Only include characters you need:

```bash

Generate subset with only Latin characters

pyftsubset font.ttf --output-file=font-subset.woff2 --flavor=woff2 --unicodes=U+0020-007F ```

Use system fonts

Fastest option - no download needed:

```css font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif; ```

9. Database Query Optimization

Slow queries = slow page loads.

Add Indexes

```sql -- Before: Full table scan (slow) SELECT * FROM users WHERE email = '[email protected]';

-- After: Create index CREATE INDEX idx_users_email ON users(email); -- Now lookup is instant ```

Use Connection Pooling

Reuse database connections instead of creating new ones:

```javascript // Instead of this (slow): const connection = await mysql.createConnection(config);

// Use connection pool: const pool = mysql.createPool(config); const connection = await pool.getConnection(); ```

Cache Query Results

```javascript // Redis cache const cached = await redis.get('user:123'); if (cached) return JSON.parse(cached);

const user = await db.query('SELECT * FROM users WHERE id = 123'); await redis.set('user:123', JSON.stringify(user), 'EX', 3600); // Cache for 1 hour return user; ```

10. Use HTTP/3

The latest version of HTTP is faster and more reliable.

Benefits:

  • Faster connection setup (0-RTT)
  • Better performance on poor networks
  • Head-of-line blocking solved

Enable on Cloudflare: Dashboard → Network → HTTP/3 → Enable

Enable on Nginx (with QUIC): ```nginx listen 443 quic reuseport; listen 443 ssl http2; ssl_protocols TLSv1.3; add_header Alt-Svc 'h3=":443"; ma=86400'; ```

Framework-Specific Tips

Framework-Specific Tips

Next.js Performance Tips

```javascript // next.config.js module.exports = { // Optimize images images: { formats: ['image/avif', 'image/webp'], deviceSizes: [640, 750, 828, 1080, 1200], minimumCacheTTL: 60, },

// Enable SWC minification (faster than Terser) swcMinify: true,

// Disable source maps in production productionBrowserSourceMaps: false,

// Enable compression compress: true,

// Optimize fonts optimizeFonts: true,

// Experimental features experimental: { optimizeCss: true, // Optimize CSS modernBuild: true, // Smaller bundles for modern browsers }, }; ```

Use Server Components (App Router): ```tsx // app/page.tsx - Server Component by default export default async function Page() { // This runs on server, no JavaScript sent to client const data = await fetchData(); return <div>{data}</div>; } ```

React Optimization

Memoization: ```jsx import { memo, useMemo, useCallback } from 'react';

// Prevent re-renders if props haven't changed const ExpensiveComponent = memo(({ data }) => { return <div>{data}</div>; });

// Memoize expensive calculations function Component({ items }) { const total = useMemo(() => { return items.reduce((sum, item) => sum + item.price, 0); }, [items]); // Only recalculate if items change

return <div>Total: {total}</div>; }

// Memoize callback functions function Parent() { const handleClick = useCallback(() => { console.log('clicked'); }, []); // Function reference stays the same

return <Child onClick={handleClick} />; } ```

WordPress Speed Improvements

1. Use a caching plugin:

  • WP Rocket (paid, best overall)
  • W3 Total Cache (free)
  • WP Super Cache (free, simple)

2. Optimize database:

  • WP-Optimize plugin (clean revisions, drafts, spam)

3. Use a fast theme:

  • GeneratePress
  • Astra
  • Neve

4. Minimize plugins:

  • Each plugin adds overhead
  • Deactivate unused plugins
  • Use lightweight alternatives

5. Use a good host:

  • Avoid budget shared hosting
  • Use managed WordPress hosting (WP Engine, Kinsta, Flywheel)
Measuring & Monitoring Performance

Measuring & Monitoring Performance

Real User Monitoring (RUM)

Track actual user experience:

```javascript import { getCLS, getFID, getLCP, getFCP, getTTFB } from 'web-vitals';

function sendToAnalytics(metric) { // Send to your analytics platform const body = JSON.stringify({ name: metric.name, value: metric.value, id: metric.id, });

if (navigator.sendBeacon) { navigator.sendBeacon('/analytics', body); } else { fetch('/analytics', { body, method: 'POST', keepalive: true }); } }

getCLS(sendToAnalytics); getFID(sendToAnalytics); getLCP(sendToAnalytics); getFCP(sendToAnalytics); getTTFB(sendToAnalytics); ```

Tools to Use

Free Tools:

  • Google PageSpeed Insights - Field + lab data
  • RoastWeb - Comprehensive audit in 10 seconds
  • WebPageTest - Detailed waterfall analysis
  • Chrome DevTools Lighthouse - Built into browser

Paid Tools:

  • SpeedCurve - Performance monitoring over time
  • Calibre - Performance budgets and alerts
  • Pingdom - Uptime and performance monitoring
Common Performance Mistakes to Avoid

Common Performance Mistakes to Avoid

1. Not Testing on Real Devices

Simulators lie. Test on real mobile devices with real network conditions (3G, 4G).

2. Optimizing the Wrong Pages

Focus on:

  • Homepage (first impression)
  • Top landing pages (where users enter)
  • Conversion pages (checkout, signup)

Don't obsess over rarely-visited pages.

3. Ignoring Network Conditions

Test on slow connections:

  • Chrome DevTools → Network → Slow 3G
  • WebPageTest → Select "Mobile 3G - Fast" location

4. Loading Everything Upfront

Use lazy loading, code splitting, and deferred scripts.

5. No Performance Budget

Set limits and enforce them:

  • Max bundle size: 200KB (JavaScript)
  • Max LCP: 2.5s
  • Max image size: 100KB

Fail builds if budget is exceeded:

```json // package.json { "bundlesize": [ { "path": "./dist/**/*.js", "maxSize": "200 kB" } ] } ```

Conclusion: Performance Optimization Checklist

Conclusion: Performance Optimization Checklist

Quick Wins (Do Today):

  • [ ] Run a performance audit (RoastWeb.com)
  • [ ] Enable Gzip/Brotli compression
  • [ ] Add `loading="lazy"` to images
  • [ ] Defer non-critical JavaScript
  • [ ] Enable browser caching

Medium Effort (This Week):

  • [ ] Compress images (use WebP format)
  • [ ] Implement CDN
  • [ ] Minimize and bundle CSS/JS
  • [ ] Optimize web fonts (font-display: swap)
  • [ ] Remove unused third-party scripts

Long Term (This Month):

  • [ ] Implement code splitting
  • [ ] Add service worker for caching
  • [ ] Optimize database queries
  • [ ] Set up Real User Monitoring (RUM)
  • [ ] Create performance budget

Remember: Performance is not a one-time fix. It's an ongoing process. Monitor regularly and keep optimizing.

Start testing your site now: Get a Free Performance Audit at RoastWeb.com →

Key Takeaways

Key Takeaways

What You've Learned:

  • Core Web Vitals targets for 2025: LCP <2.5s, INP <200ms, CLS <0.1 are direct ranking factors
  • 53% of mobile users abandon sites taking longer than 3 seconds to load
  • Images account for 50-70% of average page weight - optimizing them yields dramatic improvements
  • WebP format is 25-35% smaller than JPEG; AVIF is 50% smaller but has less browser support
  • Third-party scripts are the #1 cause of slow websites (analytics, ads, chat widgets)
  • Every 100ms of latency costs Amazon 1% in sales - speed directly impacts revenue

Quick Wins:

  1. Run RoastWeb performance audit to identify critical issues (10 seconds)
  2. Convert your hero images to WebP format with TinyPNG or Squoosh (20 min)
  3. Add `loading="lazy"` attribute to all below-the-fold images (15 min)
  4. Enable Cloudflare CDN free plan for instant global delivery (30 min)
  5. Defer non-critical JavaScript with `defer` attribute (20 min)

Frequently Asked Questions (FAQ)

What is a good website load time in 2025?

Under 2.5 seconds for Largest Contentful Paint (LCP). Google's Core Web Vitals targets: LCP <2.5s, INP <200ms, CLS <0.1. Achieving these puts you in the "Good" range and positively impacts rankings.

How do I check my website performance?

Use Google PageSpeed Insights (free, real user data + lab data), RoastWeb (comprehensive 10-second audit), or WebPageTest (detailed waterfall analysis). Test both mobile and desktop performance.

What slows down a website the most?

The top culprits are: unoptimized images (30-50% of page weight), excessive JavaScript (render-blocking), no CDN, slow server response (TTFB >600ms), and third-party scripts (ads, analytics).

Does website speed affect SEO?

Yes, directly. Google confirmed page speed is a ranking factor. Core Web Vitals (LCP, INP, CLS) are part of the "Page Experience" update. Faster sites rank higher and have lower bounce rates.

What's the fastest way to improve website performance?

Quick wins: (1) Compress and convert images to WebP, (2) Enable Gzip/Brotli compression, (3) Use a CDN like Cloudflare (free plan available), (4) Minify CSS/JS, (5) Remove unused third-party scripts. These can improve load time by 40-60%.

Is a CDN necessary for small websites?

Yes, even for small sites. CDNs like Cloudflare offer free plans and provide: faster load times (content served from nearby servers), DDoS protection, free SSL certificates, and reduced bandwidth costs.

TEST YOUR
WEBSITE NOW

Get a free, brutally honest audit in 10 seconds.

ROAST MY SITE →