Skip to main content
Comprehensive Guide 2025

Website Performance Optimization

The complete guide to optimizing your website performance. From Core Web Vitals to image optimization and caching - everything with practical code examples.

15 min read
2500+ words
Code examples

Why website performance is crucial

Website performance has been an official Google ranking factor since 2021. With the introduction of Core Web Vitals, Google has defined clear metrics that make user experience measurable. Slow websites not only lose rankings, but also visitors and revenue.

53%
leave a website if it takes longer than 3s to load
Google Research 2024
-7%
conversion rate per 100ms additional load time
Amazon Study
+32%
higher conversion rate when improved to under 2.5s LCP
Senorit Data 2024

In competitive digital markets, performance can make the difference between success and failure. A fast website is not only SEO-relevant, but directly revenue-relevant.

Largest Contentful Paint (LCP)

LCP measures how long it takes for the largest visible content element in the viewport to load. This is often a hero image, large heading, or video. Google recommends an LCP under 2.5 seconds.

Benchmarks

Good
< 2.5s
Needs improvement
2.5s - 4s
Poor
>4s

Optimization measures

1. Optimize server response time

TTFB (Time to First Byte) should be under 600ms. We recommend fast hosting providers for optimal server response times.

Nginx Configuration
# Nginx Performance Tuning
worker_processes auto;
worker_connections 4096;

# Gzip Compression
gzip on;
gzip_vary on;
gzip_min_length 1024;
gzip_types text/plain text/css text/xml text/javascript
           application/json application/javascript application/xml+rss;

# Caching
proxy_cache_path /var/cache/nginx levels=1:2
                 keys_zone=my_cache:10m max_size=1g
                 inactive=60m use_temp_path=off;

2. Prioritize resources with preload

Critical resources like hero images or important fonts should be preloaded.

HTML Head
<!-- Preload critical resources -->
<link rel="preload" as="image" href="/hero-image.webp"
      type="image/webp" fetchpriority="high">
<link rel="preload" as="font" href="/fonts/main.woff2"
      type="font/woff2" crossorigin>

<!-- Preconnect to external domains -->
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="dns-prefetch" href="https://analytics.google.com">

3. Deliver images optimally

Use modern image formats (WebP, AVIF) and responsive images with srcset.

HTML
<picture>
  <!-- AVIF for modern browsers -->
  <source type="image/avif"
          srcset="hero-400.avif 400w,
                  hero-800.avif 800w,
                  hero-1200.avif 1200w"
          sizes="(max-width: 600px) 400px,
                 (max-width: 1200px) 800px,
                 1200px">

  <!-- WebP Fallback -->
  <source type="image/webp"
          srcset="hero-400.webp 400w,
                  hero-800.webp 800w,
                  hero-1200.webp 1200w"
          sizes="(max-width: 600px) 400px,
                 (max-width: 1200px) 800px,
                 1200px">

  <!-- JPEG Fallback -->
  <img src="hero-800.jpg"
       alt="Hero Image"
       loading="eager"
       fetchpriority="high"
       width="1200"
       height="600">
</picture>

First Input Delay (FID) / Interaction to Next Paint (INP)

Update 2024: Google is replacing FID with INP (Interaction to Next Paint) in March 2024. INP measures response time to all user interactions, not just the first.

FID/INP measures the time between the first user interaction (click, tap) and the browser response. A good FID is under 100ms, a good INP under 200ms.

Optimization measures

1. Reduce JavaScript execution

Large JavaScript code blocks the main thread. Code splitting and lazy loading are essential.

Webpack/Vite Config
// Dynamic Imports for code splitting
const HeavyComponent = lazy(() => import('./HeavyComponent'));

// React.lazy with Suspense
<Suspense fallback={<Loading />}>
  <HeavyComponent />
</Suspense>

// Webpack Magic Comments for chunk names
import(/* webpackChunkName: "analytics" */ './analytics');

2. Avoid long tasks

Tasks over 50ms block user interactions. Use Web Workers for compute-intensive operations.

Web Worker Example
// Main Thread
const worker = new Worker('heavy-calculation.js');

worker.postMessage({ data: largeDataset });

worker.onmessage = (e) => {
  
  updateUI(e.data);
};

// heavy-calculation.js (Worker)
self.onmessage = (e) => {
  const result = performHeavyCalculation(e.data);
  self.postMessage(result);
};

3. Optimize third-party scripts

Analytics, chatbots and other third-party scripts should be loaded async or with defer.

HTML
<!-- Load asynchronously -->
<script async src="https://www.googletagmanager.com/gtag/js"></script>

<!-- With defer for better timing -->
<script defer src="/analytics.js"></script>

<!-- Self-hosted instead of CDN for better performance -->
<script defer src="/libs/jquery.min.js"></script>

Cumulative Layout Shift (CLS)

CLS measures the visual stability of a page. When elements "jump" during loading, it leads to poor user experience. A good CLS is under 0.1.

Common CLS causes

Images without dimensions

Browser doesn't know the size and reserves no space

Dynamically inserted ads or banners

Content appears after initial rendering

Web fonts without font-display

FOIT (Flash of Invisible Text) shifts layout

Solutions

1. Always specify width and height

<!-- Explicit dimensions -->
<img src="logo.png" alt="Logo" width="200" height="50">

<!-- Or aspect-ratio in CSS -->
<img src="hero.jpg" alt="Hero" style="aspect-ratio: 16/9; width: 100%;">

<!-- Modern with CSS aspect-ratio -->
.hero-image {
  width: 100%;
  aspect-ratio: 16 / 9;
  object-fit: cover;
}

2. Reserve space for dynamic content

<!-- Skeleton screen for ads -->
.ad-placeholder {
  width: 100%;
  height: 250px;
  background: linear-gradient(90deg, #f0f0f0 25%, #e0e0e0 50%, #f0f0f0 75%);
  background-size: 200% 100%;
  animation: loading 1.5s infinite;
}

@keyframes loading {
  0% { background-position: 200% 0; }
  100% { background-position: -200% 0; }
}

3. Optimize font loading

/* font-display for better fallback */
@font-face {
  font-family: 'CustomFont';
  src: url('/fonts/custom.woff2') format('woff2');
  font-display: swap; /* Shows fallback immediately */
  font-weight: 400;
  font-style: normal;
}

/* Preload critical fonts */
<link rel="preload" as="font"
      href="/fonts/custom.woff2"
      type="font/woff2"
      crossorigin>

Image optimization

Images often account for 50-70% of total page size. Optimization is the biggest performance lever.

Format comparison

Format Browser support File size Recommendation
AVIF ~85% Smallest First choice for modern browsers
WebP ~96% 30% smaller than JPEG Best fallback
JPEG 100% Baseline Legacy support
PNG 100% Largest Only for transparency

Optimization tools

Sharp (Node.js)

const sharp = require('sharp');

// Convert image to multiple formats
await sharp('input.jpg')
  .resize(1200, 800, { fit: 'cover' })
  .webp({ quality: 80 })
  .toFile('output-1200.webp');

await sharp('input.jpg')
  .resize(1200, 800, { fit: 'cover' })
  .avif({ quality: 70 })
  .toFile('output-1200.avif');

Squoosh CLI

# Installation
npm install -g @squoosh/cli

# Batch conversion to WebP
squoosh-cli --webp '{"quality":80}' images/*.jpg

# To AVIF with different sizes
squoosh-cli --avif '{"quality":70}' \
  --resize '{"width":1200}' \
  --resize '{"width":800}' \
  --resize '{"width":400}' \
  images/*.jpg

Caching strategies

Effective caching reduces server load and massively improves performance for returning visitors.

Browser caching (.htaccess)

<IfModule mod_expires.c>
  ExpiresActive On

  # Images - 1 year
  ExpiresByType image/jpeg "access plus 1 year"
  ExpiresByType image/webp "access plus 1 year"
  ExpiresByType image/avif "access plus 1 year"
  ExpiresByType image/png "access plus 1 year"
  ExpiresByType image/svg+xml "access plus 1 year"

  # CSS and JS - 1 month
  ExpiresByType text/css "access plus 1 month"
  ExpiresByType application/javascript "access plus 1 month"

  # Fonts - 1 year
  ExpiresByType font/woff2 "access plus 1 year"
  ExpiresByType font/woff "access plus 1 year"

  # HTML - 1 hour
  ExpiresByType text/html "access plus 1 hour"
</IfModule>

Service Worker caching

// service-worker.js
const CACHE_NAME = 'v1';
const urlsToCache = [
  '/',
  '/styles/main.css',
  '/scripts/main.js',
  '/images/logo.png'
];

// Install Event - Cache resources
self.addEventListener('install', (event) => {
  event.waitUntil(
    caches.open(CACHE_NAME)
      .then((cache) => cache.addAll(urlsToCache))
  );
});

// Fetch Event - Cache-First Strategy
self.addEventListener('fetch', (event) => {
  event.respondWith(
    caches.match(event.request)
      .then((response) => {
        // Cache hit - return cached response
        if (response) return response;

        // Fetch from network
        return fetch(event.request);
      })
  );
});

CDN & Edge Computing

A Content Delivery Network (CDN) distributes your content across servers worldwide and delivers it from the geographically nearest location. We recommend CDNs with strong presence in your target regions.

Cloudflare

  • Free plan available
  • DDoS protection included
  • Edge Functions for SSR

BunnyCDN

  • Very affordable ($1/TB)
  • Best performance in Europe
  • Image optimization included

Hosting recommendations

For optimal performance, we recommend hosting providers with servers in your target region or with global CDN coverage.

Hetzner

Servers in Germany (Nuremberg & Falkenstein)

From $4/mo
Cloud Server
  • • Best performance/price ratio in Germany
  • • 20 TB traffic included
  • • Very low latency in Europe (<10ms)
Recommended for: SMBs, startups, high-traffic websites

DigitalOcean

Global datacenters (Frankfurt, London, NYC)

From $6/mo
Droplet
  • • Developer-friendly platform
  • • Managed databases and Kubernetes
  • • Easy scaling and backups
Recommended for: Web applications, API hosting

Vercel / Netlify

Edge network (global CDN)

Free
Hobby plan
  • • Perfect for Jamstack (Astro, Next.js, etc.)
  • • Automatic deployments via Git
  • • Global CDN included
Recommended for: Modern web apps, static sites, headless CMS

Save guide as PDF

Print this guide as PDF or share it with your team.

Request performance audit

Professional performance optimization

Let us analyze your website and bring it to top performance. We optimize Core Web Vitals, reduce load times, and increase your conversion rate.