`n

Website Speed Optimization Techniques - Complete Guide

Published: September 25, 2024 | Reading time: 25 minutes

Website Speed Optimization Overview

Website speed optimization improves user experience and search rankings:

Speed Optimization Benefits
# Speed Optimization Benefits
- Improved user experience
- Better search rankings
- Higher conversion rates
- Reduced bounce rates
- Mobile performance
- Core Web Vitals compliance
- SEO advantages

Core Web Vitals

Google's Core Web Vitals

Core Web Vitals Metrics

  • LCP (Largest Contentful Paint)
  • FID (First Input Delay)
  • CLS (Cumulative Layout Shift)
  • FCP (First Contentful Paint)
  • TTI (Time to Interactive)

Performance Thresholds

  • LCP: < 2.5 seconds
  • FID: < 100 milliseconds
  • CLS: < 0.1
  • FCP: < 1.8 seconds
  • TTI: < 3.8 seconds

Image Optimization

Image Compression Techniques

Image Optimization Implementation
# Image Optimization Script
#!/bin/bash
# image-optimizer.sh

# Configuration
INPUT_DIR="/var/www/images"
OUTPUT_DIR="/var/www/images/optimized"
QUALITY=85
MAX_WIDTH=1920

# Create output directory
mkdir -p $OUTPUT_DIR

# Optimize JPEG images
find $INPUT_DIR -name "*.jpg" -o -name "*.jpeg" | while read file; do
    filename=$(basename "$file")
    echo "Optimizing $filename..."
    
    # Resize and compress
    convert "$file" \
        -resize "${MAX_WIDTH}x>" \
        -quality $QUALITY \
        -strip \
        -interlace Plane \
        "$OUTPUT_DIR/$filename"
done

# Optimize PNG images
find $INPUT_DIR -name "*.png" | while read file; do
    filename=$(basename "$file")
    echo "Optimizing $filename..."
    
    # Compress PNG
    pngquant --quality=65-80 --ext .png --force "$file"
    
    # Move optimized file
    mv "${file%.*}-fs8.png" "$OUTPUT_DIR/$filename"
done

# Generate WebP versions
find $INPUT_DIR -name "*.jpg" -o -name "*.jpeg" -o -name "*.png" | while read file; do
    filename=$(basename "$file" | sed 's/\.[^.]*$//')
    echo "Generating WebP for $filename..."
    
    cwebp -q $QUALITY "$file" -o "$OUTPUT_DIR/${filename}.webp"
done

# HTML Implementation
# Responsive images with WebP fallback

    
    
    Description


# CSS Implementation
# Responsive images
.responsive-image {
    max-width: 100%;
    height: auto;
    display: block;
}

# Lazy loading implementation
img[loading="lazy"] {
    opacity: 0;
    transition: opacity 0.3s;
}

img[loading="lazy"].loaded {
    opacity: 1;
}

CSS Optimization

CSS Performance Techniques

CSS Optimization Strategies
# CSS Optimization Techniques

# 1. Critical CSS Inlining
# Extract critical CSS for above-the-fold content
const critical = require('critical');

critical.generate({
    inline: true,
    base: 'dist/',
    src: 'index.html',
    dest: 'index.html',
    width: 1300,
    height: 900,
    minify: true
});

# 2. CSS Minification
# Using PostCSS with plugins
module.exports = {
    plugins: [
        require('autoprefixer'),
        require('cssnano')({
            preset: 'default',
        }),
        require('postcss-combine-duplicated-selectors'),
        require('postcss-combine-media-query')
    ]
}

# 3. CSS Purging
# Remove unused CSS
const purgecss = require('@fullhuman/postcss-purgecss');

module.exports = {
    plugins: [
        purgecss({
            content: ['./src/**/*.html', './src/**/*.js'],
            defaultExtractor: content => content.match(/[\w-/:]+(?

# Load non-critical CSS asynchronously



# 5. CSS Architecture
# Use CSS custom properties for theming
:root {
    --primary-color: #007bff;
    --secondary-color: #6c757d;
    --font-size-base: 1rem;
    --line-height-base: 1.5;
}

.button {
    background-color: var(--primary-color);
    font-size: var(--font-size-base);
    line-height: var(--line-height-base);
}

# 6. CSS Performance Best Practices
# Avoid expensive selectors
/* Bad */
div > ul > li > a { }

/* Good */
.nav-link { }

# Use efficient selectors
/* Bad */
* { margin: 0; }

/* Good */
body, h1, h2, h3, p { margin: 0; }

# Minimize reflows and repaints
.element {
    transform: translateX(100px); /* Use transform instead of left */
    opacity: 0.5; /* Use opacity instead of visibility */
}

JavaScript Optimization

JavaScript Performance Techniques

JavaScript Optimization Strategies
# JavaScript Optimization Techniques

# 1. Code Splitting
# Webpack configuration
const path = require('path');

module.exports = {
    entry: './src/index.js',
    output: {
        filename: '[name].[contenthash].js',
        path: path.resolve(__dirname, 'dist'),
        clean: true
    },
    optimization: {
        splitChunks: {
            chunks: 'all',
            cacheGroups: {
                vendor: {
                    test: /[\\/]node_modules[\\/]/,
                    name: 'vendors',
                    chunks: 'all'
                }
            }
        }
    }
};

# Dynamic imports
// Lazy load components
const loadComponent = async () => {
    const { default: Component } = await import('./Component.js');
    return Component;
};

// Route-based code splitting
const routes = [
    {
        path: '/',
        component: () => import('./pages/Home.js')
    },
    {
        path: '/about',
        component: () => import('./pages/About.js')
    }
];

# 2. Bundle Optimization
# Tree shaking configuration
module.exports = {
    mode: 'production',
    optimization: {
        usedExports: true,
        sideEffects: false
    }
};

# 3. JavaScript Performance Best Practices
# Debouncing and throttling
function debounce(func, wait) {
    let timeout;
    return function executedFunction(...args) {
        const later = () => {
            clearTimeout(timeout);
            func(...args);
        };
        clearTimeout(timeout);
        timeout = setTimeout(later, wait);
    };
}

function throttle(func, limit) {
    let inThrottle;
    return function() {
        const args = arguments;
        const context = this;
        if (!inThrottle) {
            func.apply(context, args);
            inThrottle = true;
            setTimeout(() => inThrottle = false, limit);
        }
    };
}

# 4. Memory Management
# Avoid memory leaks
class Component {
    constructor() {
        this.elements = [];
        this.setupEventListeners();
    }
    
    setupEventListeners() {
        document.addEventListener('click', this.handleClick.bind(this));
    }
    
    destroy() {
        // Clean up event listeners
        document.removeEventListener('click', this.handleClick.bind(this));
        this.elements = null;
    }
}

# 5. Async/Await Optimization
# Efficient async operations
async function fetchData() {
    try {
        const [users, posts, comments] = await Promise.all([
            fetch('/api/users'),
            fetch('/api/posts'),
            fetch('/api/comments')
        ]);
        
        return {
            users: await users.json(),
            posts: await posts.json(),
            comments: await comments.json()
        };
    } catch (error) {
        console.error('Error fetching data:', error);
    }
}

Server-Side Optimization

Backend Performance Techniques

Server-Side Optimization
# Server-Side Optimization Techniques

# 1. HTTP/2 Configuration
# Nginx HTTP/2 setup
server {
    listen 443 ssl http2;
    server_name example.com;
    
    ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
    
    # HTTP/2 push
    location / {
        http2_push /css/style.css;
        http2_push /js/app.js;
    }
}

# 2. Compression Configuration
# Gzip compression
gzip on;
gzip_vary on;
gzip_min_length 1024;
gzip_proxied any;
gzip_comp_level 6;
gzip_types
    text/plain
    text/css
    text/xml
    text/javascript
    application/json
    application/javascript
    application/xml+rss
    application/atom+xml
    image/svg+xml;

# Brotli compression
brotli on;
brotli_comp_level 6;
brotli_types
    text/plain
    text/css
    application/json
    application/javascript
    text/xml
    application/xml
    application/xml+rss
    text/javascript;

# 3. Caching Headers
# Static assets caching
location ~* \.(css|js|png|jpg|jpeg|gif|ico|svg)$ {
    expires 1y;
    add_header Cache-Control "public, immutable";
    add_header Vary Accept-Encoding;
}

# HTML caching
location ~* \.html$ {
    expires 1h;
    add_header Cache-Control "public, must-revalidate";
}

# 4. Database Optimization
# Connection pooling
const mysql = require('mysql2/promise');

const pool = mysql.createPool({
    host: 'localhost',
    user: 'user',
    password: 'password',
    database: 'database',
    waitForConnections: true,
    connectionLimit: 10,
    queueLimit: 0,
    acquireTimeout: 60000,
    timeout: 60000
});

# Query optimization
// Use prepared statements
const [rows] = await pool.execute(
    'SELECT * FROM users WHERE id = ? AND status = ?',
    [userId, 'active']
);

// Use indexes
CREATE INDEX idx_user_status ON users(status);
CREATE INDEX idx_user_email ON users(email);

# 5. API Response Optimization
# Response compression middleware
const compression = require('compression');
app.use(compression());

# Response caching
const redis = require('redis');
const client = redis.createClient();

app.get('/api/data', async (req, res) => {
    const cacheKey = `data:${req.query.id}`;
    
    try {
        // Check cache first
        const cached = await client.get(cacheKey);
        if (cached) {
            return res.json(JSON.parse(cached));
        }
        
        // Fetch from database
        const data = await fetchDataFromDB(req.query.id);
        
        // Cache for 1 hour
        await client.setex(cacheKey, 3600, JSON.stringify(data));
        
        res.json(data);
    } catch (error) {
        res.status(500).json({ error: 'Internal server error' });
    }
});

Performance Monitoring

Performance Monitoring Setup

Performance Monitoring Implementation
# Performance Monitoring Setup

# 1. Web Vitals Monitoring
# Google Analytics 4 with Core Web Vitals
gtag('config', 'GA_MEASUREMENT_ID', {
    custom_map: {
        'custom_parameter_1': 'web_vitals'
    }
});

# Web Vitals measurement
import {getCLS, getFID, getFCP, getLCP, getTTFB} from 'web-vitals';

function sendToAnalytics(metric) {
    gtag('event', metric.name, {
        event_category: 'Web Vitals',
        event_label: metric.id,
        value: Math.round(metric.name === 'CLS' ? metric.value * 1000 : metric.value),
        non_interaction: true,
    });
}

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

# 2. Performance Observer API
# Monitor performance metrics
const observer = new PerformanceObserver((list) => {
    for (const entry of list.getEntries()) {
        console.log(entry.name, entry.duration);
        
        // Send to analytics
        if (entry.entryType === 'navigation') {
            sendToAnalytics({
                name: 'TTFB',
                value: entry.responseStart - entry.requestStart
            });
        }
    }
});

observer.observe({entryTypes: ['navigation', 'paint', 'largest-contentful-paint']});

# 3. Real User Monitoring (RUM)
# Custom performance monitoring
class PerformanceMonitor {
    constructor() {
        this.metrics = {};
        this.init();
    }
    
    init() {
        // Monitor page load time
        window.addEventListener('load', () => {
            this.metrics.pageLoadTime = performance.now();
            this.sendMetrics();
        });
        
        // Monitor resource loading
        this.monitorResources();
        
        // Monitor user interactions
        this.monitorInteractions();
    }
    
    monitorResources() {
        const resources = performance.getEntriesByType('resource');
        resources.forEach(resource => {
            if (resource.duration > 1000) { // Resources taking more than 1 second
                this.metrics.slowResources = this.metrics.slowResources || [];
                this.metrics.slowResources.push({
                    name: resource.name,
                    duration: resource.duration
                });
            }
        });
    }
    
    monitorInteractions() {
        let interactionCount = 0;
        const startTime = performance.now();
        
        ['click', 'keydown', 'scroll'].forEach(eventType => {
            document.addEventListener(eventType, () => {
                interactionCount++;
                
                if (interactionCount === 1) {
                    this.metrics.firstInteraction = performance.now() - startTime;
                }
            });
        });
    }
    
    sendMetrics() {
        // Send to analytics service
        fetch('/api/performance', {
            method: 'POST',
            headers: {
                'Content-Type': 'application/json'
            },
            body: JSON.stringify(this.metrics)
        });
    }
}

new PerformanceMonitor();

# 4. Lighthouse CI Integration
# Automated performance testing
module.exports = {
    ci: {
        collect: {
            url: ['http://localhost:3000'],
            numberOfRuns: 3
        },
        assert: {
            assertions: {
                'categories:performance': ['error', {minScore: 0.9}],
                'categories:accessibility': ['error', {minScore: 0.9}],
                'categories:best-practices': ['error', {minScore: 0.9}],
                'categories:seo': ['error', {minScore: 0.9}]
            }
        },
        upload: {
            target: 'temporary-public-storage'
        }
    }
};

Mobile Optimization

Mobile Performance Techniques

Mobile Optimization Strategies
# Mobile Optimization Techniques

# 1. Responsive Images
# Picture element with multiple sources

    
    
    
    Description


# 2. Touch Optimization
# Touch-friendly interfaces
.touch-target {
    min-height: 44px;
    min-width: 44px;
    padding: 12px;
}

# Prevent zoom on input focus
input, select, textarea {
    font-size: 16px;
}

# 3. Mobile-First CSS
# Mobile-first approach
.container {
    width: 100%;
    padding: 1rem;
}

@media (min-width: 768px) {
    .container {
        max-width: 750px;
        margin: 0 auto;
    }
}

@media (min-width: 1024px) {
    .container {
        max-width: 1200px;
    }
}

# 4. Progressive Web App (PWA)
# Service Worker for caching
const CACHE_NAME = 'app-cache-v1';
const urlsToCache = [
    '/',
    '/css/style.css',
    '/js/app.js',
    '/images/logo.png'
];

self.addEventListener('install', (event) => {
    event.waitUntil(
        caches.open(CACHE_NAME)
            .then((cache) => cache.addAll(urlsToCache))
    );
});

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

# 5. Mobile Performance Best Practices
# Reduce JavaScript execution
// Use requestIdleCallback for non-critical tasks
function processData() {
    // Heavy computation
}

if ('requestIdleCallback' in window) {
    requestIdleCallback(processData);
} else {
    setTimeout(processData, 1);
}

# Optimize for mobile networks
// Detect connection speed
const connection = navigator.connection || navigator.mozConnection || navigator.webkitConnection;

if (connection) {
    if (connection.effectiveType === 'slow-2g' || connection.effectiveType === '2g') {
        // Load minimal resources
        loadMinimalVersion();
    } else {
        // Load full version
        loadFullVersion();
    }
}

# 6. Mobile-Specific Optimizations
# Viewport configuration


# Preload critical resources


Performance Testing Tools

Performance Testing Setup

Performance Testing Tools
# Performance Testing Tools

# 1. Lighthouse CLI
# Install Lighthouse
npm install -g lighthouse

# Run Lighthouse audit
lighthouse http://localhost:3000 --output html --output-path ./lighthouse-report.html

# Lighthouse CI configuration
module.exports = {
    ci: {
        collect: {
            url: ['http://localhost:3000'],
            numberOfRuns: 3
        },
        assert: {
            assertions: {
                'categories:performance': ['error', {minScore: 0.9}],
                'first-contentful-paint': ['error', {maxNumericValue: 2000}],
                'largest-contentful-paint': ['error', {maxNumericValue: 2500}],
                'cumulative-layout-shift': ['error', {maxNumericValue: 0.1}]
            }
        }
    }
};

# 2. WebPageTest Integration
# WebPageTest API
const webpagetest = require('webpagetest');

const wpt = new webpagetest('https://www.webpagetest.org');

wpt.runTest('http://example.com', {
    runs: 3,
    location: 'Dulles:Chrome',
    firstViewOnly: false
}, (err, data) => {
    if (err) {
        console.error(err);
        return;
    }
    
    console.log('Test ID:', data.testId);
    
    // Check results
    wpt.getTestResults(data.testId, (err, results) => {
        if (err) {
            console.error(err);
            return;
        }
        
        console.log('First View Load Time:', results.data.average.firstView.loadTime);
        console.log('Speed Index:', results.data.average.firstView.SpeedIndex);
    });
});

# 3. Performance Budget
# Webpack performance budget
module.exports = {
    performance: {
        maxAssetSize: 250000,
        maxEntrypointSize: 250000,
        hints: 'warning'
    }
};

# 4. Automated Performance Testing
# Jest performance tests
describe('Performance Tests', () => {
    test('page load time should be under 3 seconds', async () => {
        const startTime = Date.now();
        
        await page.goto('http://localhost:3000');
        await page.waitForLoadState('networkidle');
        
        const loadTime = Date.now() - startTime;
        expect(loadTime).toBeLessThan(3000);
    });
    
    test('LCP should be under 2.5 seconds', async () => {
        await page.goto('http://localhost:3000');
        
        const lcp = await page.evaluate(() => {
            return new Promise((resolve) => {
                new PerformanceObserver((list) => {
                    const entries = list.getEntries();
                    const lastEntry = entries[entries.length - 1];
                    resolve(lastEntry.startTime);
                }).observe({entryTypes: ['largest-contentful-paint']});
            });
        });
        
        expect(lcp).toBeLessThan(2500);
    });
});

# 5. Performance Monitoring Dashboard
# Real-time performance monitoring
const express = require('express');
const app = express();

// Performance metrics endpoint
app.get('/api/performance', (req, res) => {
    const metrics = {
        timestamp: Date.now(),
        url: req.query.url,
        metrics: {
            fcp: req.query.fcp,
            lcp: req.query.lcp,
            fid: req.query.fid,
            cls: req.query.cls
        }
    };
    
    // Store metrics in database
    storeMetrics(metrics);
    
    res.json({status: 'success'});
});

// Performance dashboard
app.get('/dashboard', (req, res) => {
    const metrics = getMetrics();
    res.render('dashboard', {metrics});
});

Best Practices

Performance Optimization Checklist

Frontend Optimization

  • Optimize images and use WebP
  • Minify CSS and JavaScript
  • Implement lazy loading
  • Use critical CSS
  • Enable compression
  • Implement caching
  • Use CDN for static assets

Backend Optimization

  • Enable HTTP/2
  • Implement database indexing
  • Use connection pooling
  • Optimize database queries
  • Implement caching layers
  • Use compression
  • Monitor performance metrics

Summary

Website speed optimization involves several key components:

  • Core Web Vitals: LCP, FID, CLS monitoring and optimization
  • Image Optimization: Compression, WebP, responsive images
  • CSS Optimization: Critical CSS, minification, purging
  • JavaScript Optimization: Code splitting, bundling, performance
  • Server Optimization: HTTP/2, compression, caching
  • Performance Monitoring: Web Vitals, RUM, automated testing
  • Mobile Optimization: Responsive design, PWA, touch optimization
  • Testing Tools: Lighthouse, WebPageTest, performance budgets

Need More Help?

Struggling with website speed optimization or need help improving your Core Web Vitals? Our performance experts can help you optimize your website for better speed and user experience.

Get Performance Help