Frontend Development 15 min read

Understanding HTTP Caching and Service Workers for Frontend Performance Optimization

This article explains the fundamentals of HTTP caching, the role of Service Workers, various cache layers (memory, disk, push), cache-control directives, and provides practical code examples to help front‑end developers improve page load speed and reduce server load.

HomeTech
HomeTech
HomeTech
Understanding HTTP Caching and Service Workers for Frontend Performance Optimization

Introduction

The article introduces web performance optimization, noting that traditional techniques (Yahoo’s 35 rules, sprite images, SEO) have been superseded by modern tooling such as Node.js, ES modules, and build pipelines, but caching remains a simple yet powerful strategy.

Concept of HTTP Cache

According to Wikipedia, HTTP cache temporarily stores web documents (HTML, images, etc.) to reduce server latency. Cache can exist at the browser, proxy, or server level.

Advantages

Accelerates page rendering and improves user experience.

Reduces redundant data transfer, saving bandwidth.

Alleviates server load in high‑traffic scenarios.

Service Worker Overview

Service Workers act as a proxy between the web app and the network, enabling offline experiences, request interception, and cache management. They run on HTTPS or localhost for security.

Key Features

Operate off the main thread and control all page requests.

Persist until manually unregistered.

Use the fetch API together with caches to manage resources.

Registering a Service Worker

if ('serviceWorker' in navigator) {
  navigator.serviceWorker.register('/sw.js')
    .then(function(registration) {
      console.log('ServiceWorker registration successful with scope: ', registration.scope);
    })
    .catch(function(err) {
      console.log('ServiceWorker registration failed: ', err);
    });
}

Installation Phase

const VERSION = 'v1';
const CACHE_FILES = [
  'js/app.js',
  'css/style.css'
];
self.addEventListener('install', function(event) {
  event.waitUntil(
    new Promise(function() {
      caches.open(VERSION)
        .then(function(cache) {
          console.log('Opened cache');
          return cache.addAll(CACHE_FILES);
        });
      self.skipWaiting();
    })
  );
});

Activation and Cache Update

self.addEventListener('activate', function(event) {
  event.waitUntil(
    caches.keys().then(function(cacheNames) {
      return Promise.all(
        cacheNames.map(function(cacheName) {
          if (cacheName !== VERSION) {
            return caches.delete(cacheName);
          }
        })
      );
    })
  );
});

Fetch Interception

self.addEventListener('fetch', function(event) {
  event.respondWith(
    caches.match(event.request).then(function(response) {
      if (response) {
        return response;
      }
      return fetch(event.request).then(function(httpRes) {
        if (!httpRes || (httpRes.status !== 200 && httpRes.status !== 304 && httpRes.type !== 'opaque') || event.request.method === 'POST') {
          return httpRes;
        }
        var responseClone = httpRes.clone();
        caches.open('my-first-sw').then(function(cache) {
          cache.put(event.request, responseClone);
        });
        return httpRes;
      });
    })
  );
});

Cache Types

Memory Cache – stores resources in RAM for fast access; cleared when the process ends.

Disk Cache – persists resources on disk; survives process termination.

Push Cache – HTTP/2 Server Push pre‑loads resources.

Cache Priority

When a request is made, the browser checks caches in this order: Service Worker → Memory Cache → Disk Cache → Push Cache. Only if none match does it request the network.

Expiration Strategies

Strong Cache

Resources are considered fresh for a defined period, controlled by Expires (absolute time) or Cache-Control (relative time, e.g., max-age ).

Expires: Sun, 08 Dec 2019 16:51:51 GMT
Cache-Control: max-age=10800

Cache-Control Directives

Directive

Description

public

Response may be cached by any cache.

private

Response is cacheable only by the client.

no-cache

Cache must revalidate with the server before using.

no-store

Do not store the response in any cache.

max-age

Maximum age in seconds before the response is considered stale.

s-maxage

Overrides max-age for shared caches.

max-stale

Client accepts a stale response up to a specified time.

min-fresh

Client wants a response that will remain fresh for at least the given seconds.

Negotiated Cache

When a strong cache miss occurs, the browser uses conditional requests to verify freshness.

Last-Modified / If-Modified-Since

The server sends Last-Modified with the resource; the client later sends If-Modified-Since . If unchanged, the server returns 304 Not Modified .

ETag / If-None-Match

ETag is a fingerprint of the content; the client sends If-None-Match . If the ETag matches, the server returns 304 . ETag has higher priority than Last-Modified.

Conclusion

The article reviews HTTP caching mechanisms, Service Worker implementation, cache layers, expiration headers, and validation strategies, providing practical code snippets for front‑end developers to improve performance and reduce server load.

cachingHTTPservice-workerfrontend performanceweb optimization
HomeTech
Written by

HomeTech

HomeTech tech sharing

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.