Unit 6.1 · Tutorial 2

Advanced Optimisation Techniques

Chapter 17 · Advanced Topics
~3 hours Advanced Images · Caching · CDN · Database

Overview

Beyond the basics, advanced performance optimisation requires a holistic approach. This tutorial covers image optimisation, caching strategies, CDN integration, database tuning, and profiling techniques that will make your application truly production‑ready.

Why this matters: Advanced optimisation reduces infrastructure costs, improves user experience, and increases conversion rates. These techniques are used by top‑tier engineering teams.

1. Image Optimisation

Images are often the largest source of page weight. Optimise them with:

  • Format selection: WebP, AVIF for modern browsers, JPEG/PNG as fallbacks.
  • Responsive images: srcset and sizes attributes.
  • Compression: Use tools like Sharp, ImageMagick, or Squoosh.
  • Lazy loading: Defer off‑screen images.
// Using Sharp for image optimisation (Node.js) import sharp from 'sharp'; async function optimiseImage(inputPath, outputPath) { await sharp(inputPath) .resize(800, 600, { fit: 'inside' }) .webp({ quality: 80 }) .toFile(outputPath); } // Generates: image.webp (80% quality, 800x600)
Description

2. Caching Strategies

Implement caching at multiple levels:

Browser Caching

// HTTP Headers (Express.js) app.use(express.static('public', { maxAge: '1y', setHeaders: (res, path) => { if (path.endsWith('.html')) { res.setHeader('Cache-Control', 'no-cache'); } else if (path.match(/\.(js|css|png|jpg|webp)$/)) { res.setHeader('Cache-Control', 'public, max-age=31536000, immutable'); } } }));

Application Caching

// Redis caching example import Redis from 'ioredis'; const redis = new Redis(); async function getCachedData(key, fetchFn) { const cached = await redis.get(key); if (cached) return JSON.parse(cached); const data = await fetchFn(); await redis.setex(key, 3600, JSON.stringify(data)); return data; } // Usage const products = await getCachedData('products', () => Product.find());

Cache‑invalidation strategies

  • TTL (Time‑To‑Live): Expire after a set time.
  • Event‑based: Invalidate on data updates.
  • Versioned keys: Increment version number on updates.

3. Content Delivery Networks (CDN)

CDNs distribute your content across global edge locations, reducing latency.

  • Static assets: Host images, CSS, JS on CDN.
  • Dynamic content: Edge caching with Cloudflare Workers or Vercel Edge.
  • Popular CDNs: Cloudflare, Akamai, Fastly, AWS CloudFront.
// Cloudflare Workers – edge cache export default { async fetch(request, env) { const url = new URL(request.url); if (url.pathname.startsWith('/api/')) { const cache = caches.default; const cached = await cache.match(request); if (cached) return cached; const response = await fetch(request); const cacheResponse = new Response(response.body, response); cacheResponse.headers.set('Cache-Control', 'public, max-age=60'); await cache.put(request, cacheResponse.clone()); return cacheResponse; } return fetch(request); } };
Benefits: Reduced latency, lower origin load, DDoS protection, and automatic scaling.

4. Database Tuning

Database performance is critical for backend responsiveness.

  • Indexing: Index columns used in WHERE, JOIN, ORDER BY, GROUP BY.
  • Query optimisation: Use EXPLAIN to analyse queries.
  • Connection pooling: Reuse database connections.
  • Read replicas: Offload read queries to replicas.
-- Using EXPLAIN to analyse a query EXPLAIN ANALYZE SELECT * FROM orders WHERE user_id = 123 AND created_at > '2026-01-01' ORDER BY created_at DESC; -- Add an index to optimise CREATE INDEX idx_orders_user_created ON orders(user_id, created_at DESC);
// Connection pooling (Node.js/TypeORM) import { DataSource } from 'typeorm'; const AppDataSource = new DataSource({ type: 'postgres', host: 'localhost', port: 5432, username: 'user', password: 'pass', database: 'mydb', poolSize: 20, extra: { max: 20, idleTimeoutMillis: 30000, }, });

5. Profiling & Monitoring

Use profiling tools to identify bottlenecks:

  • Node.js: --inspect flag with Chrome DevTools.
  • Python: Pyflame, cProfile.
  • Java: JProfiler, VisualVM.
  • Go: pprof (built‑in).
// Node.js profiling node --inspect --prof my-app.js // Go pprof import _ "net/http/pprof" // In your handler: func main() { go func() { log.Println(http.ListenAndServe("localhost:6060", nil)) }() // ... application code } // Then: go tool pprof http://localhost:6060/debug/pprof/profile

Quiz

Question 1

Which image format offers the best compression for modern browsers?

  • JPEG
  • PNG
  • WebP
  • GIF
Show answer
C. WebP (or AVIF, which is even better).

Question 2

Which cache invalidation strategy uses a fixed expiration time?

  • Event‑based invalidation
  • TTL (Time‑To‑Live)
  • Versioned keys
  • Manual invalidation
Show answer
B. TTL (Time‑To‑Live).

Question 3

What does a CDN primarily improve?

  • CPU usage
  • Latency and load times
  • Memory usage
  • Database performance
Show answer
B. Latency and load times.

Exercises

Exercise 1

Write a function that compresses an image using Sharp, resizes it to 800x600, and converts it to WebP format.

Sample answer
import sharp from 'sharp'; async function optimizeImage(inputPath, outputPath) { await sharp(inputPath) .resize(800, 600, { fit: 'cover' }) .webp({ quality: 80 }) .toFile(outputPath); console.log(`Optimised image saved to ${outputPath}`); }

Exercise 2

Write a SQL CREATE INDEX statement for a table with columns `user_id`, `created_at`, and `status` to optimise queries filtering by user and ordering by date.

Sample answer
CREATE INDEX idx_orders_user_created_status ON orders(user_id, created_at DESC, status);

This index supports queries that filter by user_id, sort by created_at, and filter by status.

Homework

Homework 1

Implement caching for your capstone project's API endpoints using Redis. Add caching for the most frequently accessed endpoint (e.g., GET /products) with a 5‑minute TTL. Document the performance improvement.

Sample outline
  • Setup: Install Redis and connect to your application.
  • Implementation: Cache the GET /products endpoint.
  • TTL: 300 seconds (5 minutes).
  • Testing: Measure response time with and without caching.
  • Documentation: Show the before/after latency improvement.

Mini‑Project

Full Performance Optimisation

Apply a comprehensive performance optimisation to your capstone project:

  • Optimise all images (convert to WebP, resize, lazy load)
  • Implement Redis caching for at least 3 API endpoints
  • Add cache headers for static assets (1 year for JS/CSS, no-cache for HTML)
  • Set up a CDN for static assets
  • Add at least 2 database indexes to improve query performance
  • Re‑run Lighthouse and document the improvement
Sample outline
  • Images: All images converted to WebP with responsive srcset.
  • Cache: Redis for products, categories, and user profiles.
  • Headers: Static assets served with immutable cache headers.
  • CDN: Cloudflare set up for static assets.
  • Indexes: Added indexes for query performance.
  • Results: Lighthouse score improved from 78 to 94.

Tutorial Summary

You learned advanced performance optimisation techniques: image optimisation, caching strategies, CDN integration, database tuning, and profiling. These techniques are essential for building high‑performance, production‑ready applications that deliver excellent user experiences.

Key takeaway: Performance optimisation is a multi‑layer effort. Address bottlenecks at every level – from images and code to databases and infrastructure.