Real-Time, Progressive and Offline Web ApplicationsIntroduction and ContextModern web applications are expected to behave less like collections of static pages and more like responsive software systems. A collaboration platform must display new messages immediately; a delivery application must update vehicle locations continuously; and a news or commerce application should remain useful when connectivity is weak or absent. These requirements are addressed by three related but distinct approaches: - Real-time communication, which allows information to move between client and server with minimal delay.
- Progressive Web Applications (PWAs), which use web standards to provide app-like installation, reliability and engagement.
- Offline-first design, which treats intermittent connectivity as a normal operating condition rather than an exceptional failure.
This chapter explains WebSockets, Server-Sent Events (SSE), service workers, web app manifests, caching strategies, offline data, push notifications, security and deployment considerations. The emphasis is on design decisions rather than merely memorising APIs. Learning ObjectivesAfter studying this chapter, you should be able to: - Explain the difference between request–response, WebSocket and SSE communication.
- Select an appropriate real-time protocol for a given application.
- Describe the lifecycle and security model of a service worker.
- Construct the essential components of a PWA, including a manifest and caching strategy.
- Design an offline-first application with synchronisation and conflict handling.
- Explain the architecture and privacy implications of push notifications.
- Evaluate reliability, performance, accessibility and governance risks in real-time PWAs.
1. Communication Models for the Modern WebTraditional HTTP follows a request–response pattern. The browser sends a request, the server returns a response, and the transaction ends. This model is efficient for documents and discrete API calls, but it does not naturally support continuous updates. A browser that wants current data must either ask repeatedly, known as polling, or maintain a longer-lived communication channel. In polling, the client sends requests at regular intervals. Short intervals reduce update delay but increase network traffic, battery use and server workload. Long intervals reduce overhead but make information stale. Long polling improves this situation by allowing the server to hold a request until data is available or a timeout occurs; however, the connection must still be recreated after each response. Real-time does not mean instantaneous. It means that the system is designed to deliver updates with sufficiently low and predictable delay for its application. A stock dashboard, online game and classroom notification system have different acceptable delays. 1.1 WebSocketsWebSockets provide a persistent, bidirectional channel between browser and server. An HTTP request begins a protocol upgrade; after a successful handshake, both parties can send messages independently over the connection. WebSockets are suitable for chat, multiplayer games, collaborative editing and live control systems. A simplified browser example is: const socket = new WebSocket("wss://example.edu/live");
socket.addEventListener("open", () => {
socket.send(JSON.stringify({ type: "subscribe", topic: "results" }));
});
socket.addEventListener("message", event => {
const message = JSON.parse(event.data);
console.log("Update:", message);
});
socket.addEventListener("close", () => {
console.log("Connection closed");
});The wss scheme encrypts the connection using TLS. Applications should validate the message type and content instead of trusting incoming JSON. A robust client also implements reconnection with bounded exponential backoff, for example increasing delays such as 1, 2, 4 and 8 seconds, with a maximum limit and random jitter. Reconnecting immediately in a loop can overload both client and server. WebSockets do not automatically provide application-level features such as authentication renewal, message ordering across multiple servers, persistence, replay or conflict resolution. These must be designed explicitly. A message identifier, event timestamp and sequence number can help detect duplicates or missing events. 1.2 Server-Sent EventsServer-Sent Events use a persistent HTTP connection through which the server sends a stream of text events to the browser. Communication is unidirectional: server to client. The browser API is EventSource. const stream = new EventSource("/events", { withCredentials: true });
stream.addEventListener("announcement", event => {
const announcement = JSON.parse(event.data);
renderAnnouncement(announcement);
});
stream.onerror = () => {
console.log("The browser will attempt to reconnect.");
};An SSE response uses the media type text/event-stream. Events may contain fields such as event, data, id and retry. Browsers can automatically reconnect, and the Last-Event-ID request header can help a server resume a stream. SSE works well for dashboards, notifications, progress reports and live logs where the client mainly receives updates. SSE is simpler than WebSockets and integrates naturally with HTTP authentication, proxies and text-based events. Its limitations include one-way communication, text-oriented payloads and practical connection limits, particularly with older HTTP/1.1 browser behaviour. HTTP/2 can improve connection efficiency, but deployment must still be tested through the actual proxy and hosting infrastructure. 1.3 Choosing Between WebSockets and SSE| Requirement | WebSockets | SSE |
|---|
| Direction | Bidirectional | Server to client | | Typical uses | Chat, games, collaborative editing | Feeds, alerts, dashboards | | Browser API | WebSocket | EventSource | | Automatic reconnection | Must usually be designed | Built into the browser API | | Data style | Text or binary | Text event stream | | HTTP simplicity | Lower after upgrade | High | | Client-to-server messages | Native channel | Separate HTTP requests required |
A normal fetch() request is preferable when updates are occasional and a persistent channel provides no meaningful benefit. Real-time infrastructure introduces connection management, scaling and observability costs. 2. Real-Time System DesignA production real-time system usually contains more than a browser and one server. A typical architecture includes a browser client, an edge proxy, an application server, an authentication mechanism and possibly a message broker. When multiple application instances serve clients, an update received by one instance must be distributed to clients connected to other instances. Redis Pub/Sub, a managed messaging service or another broker may be used, but the choice depends on delivery guarantees and operational requirements. The system should distinguish: - Ephemeral events, such as “user is typing,” which may be safely lost.
- Durable events, such as a payment confirmation, which must be stored and recoverable.
- State snapshots, which represent the current truth and allow a client to recover after missed events.
A useful design combines events with periodic or on-demand state synchronisation. If a client detects a sequence gap, it should request a snapshot or replay rather than silently displaying incomplete information. Security and ReliabilityAuthentication answers who the user is; authorisation answers what that user may receive or change. A WebSocket connection must not be treated as authorised merely because it was established successfully. The server should verify the user’s permissions for each sensitive operation. Origin checks, input validation, rate limiting and message-size limits reduce abuse. Browsers may automatically send cookies during a cross-site connection, so applications must consider Cross-Site Request Forgery risks. Secure cookies, appropriate SameSite settings, origin validation and explicit anti-CSRF measures are important. Never place long-lived bearer secrets in URLs, because URLs may enter logs and browser history. Operational metrics should include active connections, connection duration, reconnect rate, event latency, dropped messages, queue depth and error rate. These measurements help distinguish a client problem from a server or network problem. 3. Progressive Web ApplicationsA PWA is a web application enhanced with standards that support reliability, installation and integration with the operating system. It is not a separate programming language or a guarantee that every native capability is available. A PWA commonly combines HTTPS, a responsive interface, a web app manifest and a service worker. 3.1 Web App ManifestThe manifest describes application identity and presentation. A minimal example is: {
"name": "Campus Events",
"short_name": "Events",
"start_url": "/app/",
"display": "standalone",
"background_color": "#ffffff",
"theme_color": "#123456",
"icons": [
{ "src": "/icons/icon-192.png", "sizes": "192x192", "type": "image/png" },
{ "src": "/icons/icon-512.png", "sizes": "512x512", "type": "image/png" }
]
}The HTML document links the manifest with <link rel="manifest" href="/manifest.webmanifest">. Manifest fields influence installation prompts, launch behaviour, icons, theme and the initial navigation URL. They do not cache files and do not make an application work offline; those responsibilities belong primarily to the service worker and application data layer. 3.2 Service WorkersA service worker is a programmable background worker that can intercept selected network requests, manage caches and receive push-related events. It operates separately from the page and has no direct access to the DOM. Communication with a page occurs through mechanisms such as postMessage. A simplified registration is: if ("serviceWorker" in navigator) {
window.addEventListener("load", () => {
navigator.serviceWorker.register("/sw.js", { scope: "/app/" });
});
}Service workers require a secure context, normally HTTPS. localhost is treated as secure for development. Scope is important: a worker controls pages within its scope, subject to registration and response rules. The lifecycle normally includes installation, waiting, activation and control. During installation, essential resources may be cached. During activation, obsolete caches can be deleted. A newly installed worker may wait until older pages close unless the application deliberately uses skipWaiting() and clientsClaim(). Immediate takeover can be useful, but it may also create version inconsistency if an old page expects older cached resources. Version transitions must therefore be tested carefully. 4. Caching and Offline-First DesignThe Cache API stores request–response pairs. It is distinct from the HTTP cache and is controlled by application code. IndexedDB is generally more appropriate for structured records, queues and larger application data. A service worker can intercept requests using the fetch event: const STATIC_CACHE = "campus-static-v3";
const APP_SHELL = ["/app/", "/app/app.css", "/app/app.js", "/app/offline.html"];
self.addEventListener("install", event => {
event.waitUntil(
caches.open(STATIC_CACHE).then(cache => cache.addAll(APP_SHELL))
);
});
self.addEventListener("fetch", event => {
const request = event.request;
if (request.mode === "navigate") {
event.respondWith(
fetch(request).catch(() => caches.match("/app/offline.html"))
);
}
});Caching must be selective. Caching a response containing private, user-specific or rapidly changing data without an appropriate policy can expose information or display stale content. 4.1 Common Caching Strategies- Cache first: return the cache when available, then use the network as a fallback. Useful for versioned static assets.
- Network first: try the network, then use the cache if the network fails. Suitable for changing documents where freshness is preferred.
- Stale while revalidate: return cached content immediately and update the cache in the background. Useful for images and moderately changing feeds.
- Network only: use the network exclusively, often for payment or authentication operations.
- Cache only: serve only known pre-cached resources.
The correct strategy depends on data freshness, sensitivity, connectivity and user expectations. Cache invalidation can be managed through versioned cache names, content-hashed filenames and explicit deletion during activation. A cache is not a substitute for a database and should not be assumed to have unlimited capacity. 4.2 Offline-First ArchitectureOffline-first design begins by identifying the minimum valuable experience without a network. The application shell, previously viewed content, navigation and locally entered drafts may remain available. The user interface should clearly indicate whether data is current, cached or pending synchronisation. A common data flow is: - Read local data and render immediately.
- Attempt a network request.
- Merge validated server data into local storage.
- Queue user mutations when connectivity is unavailable.
- Synchronise queued mutations when a suitable connection returns.
- Report conflicts or rejected operations clearly.
The Background Sync API can support deferred work in browsers that implement it, but it is not universally available and should not be the only reliability mechanism. Applications should also attempt synchronisation on startup, on a connectivity transition and when the user explicitly requests it. #### Conflict Handling Offline edits may conflict with edits made elsewhere. A last-write-wins policy is simple but can silently discard work and depends on reliable timestamps. Version numbers, server-side validation, field-level merging or user-mediated conflict resolution are often safer. For collaborative editing, specialised operational transformation or conflict-free replicated data type techniques may be appropriate, although they add considerable complexity. 5. Push NotificationsPush notifications allow a server to request that a browser or operating system display information even when the application page is not open. The browser’s Push API uses a subscription containing an endpoint and cryptographic keys. The application server sends a message to a push service, which delivers it to the user agent. A service worker handles the push event and may display a notification. self.addEventListener("push", event => {
const data = event.data ? event.data.json() : {};
event.waitUntil(
self.registration.showNotification(data.title || "Campus update", {
body: data.body || "New information is available.",
data: { url: data.url || "/app/" }
})
);
});
self.addEventListener("notificationclick", event => {
event.notification.close();
event.waitUntil(clients.openWindow(event.notification.data.url));
});Permission must be requested in a meaningful user interaction, not immediately on page load. Notifications should be relevant, infrequent enough to avoid fatigue and accessible to users with disabilities. Sensitive information should not be exposed in notification text, especially on shared lock screens. Users need understandable controls for subscription, categories and revocation. Push delivery is not a transaction guarantee. Devices may be offline, subscriptions may expire and operating systems may apply power or privacy restrictions. Important business actions must be confirmed through a durable server workflow rather than inferred from notification delivery. 6. Integrated Application ArchitectureA robust application often combines the technologies rather than choosing only one. For example, a collaborative study planner may use: - REST or
fetch() for initial state and ordinary mutations. - WebSockets for presence and immediate collaborative events.
- IndexedDB for local tasks and an outbound mutation queue.
- A service worker for the application shell and offline navigation.
- A manifest for installation and launch configuration.
- Push notifications for reminders and important changes.
The page should treat real-time events as inputs to a state-management layer, not directly manipulate arbitrary interface elements. Events should be validated, deduplicated and applied according to their sequence or version. This separation makes testing and recovery easier. 7. Illustrative Case: Campus Events PWABackgroundA university publishes room changes, examination announcements and society events through a web portal. Students frequently access the portal on mobile devices and may encounter unreliable campus Wi-Fi. ProblemThe existing page requires repeated refreshes, provides no useful view during outages and sends excessive email reminders. Students miss urgent room changes, while administrators cannot tell whether an announcement has reached the intended audience. AnalysisRoom changes and emergency announcements are server-originated events, so SSE is sufficient for the main feed. Students do not need a persistent client-to-server channel. The application shell and recently viewed events should be available offline. A notification may alert a subscribed student, but the notification must not reveal private examination details on a lock screen. Approach and SolutionThe team implements an HTTPS PWA with a manifest and service worker. Static assets use cache-first delivery with versioned filenames. The event feed uses network-first retrieval, falling back to IndexedDB data with a visible “last updated” timestamp. SSE delivers new public announcements while the page is open. A server stores announcements durably and includes monotonically increasing event identifiers. If the client detects a gap, it requests the missing range or a fresh snapshot. Students explicitly opt in to notification categories. The service worker displays a generic message such as “A new campus announcement is available” and opens the relevant authenticated page after a click. Administrators receive metrics for active subscriptions, delivery attempts and feed freshness, but not unnecessary personal tracking data. OutcomeStudents can open the application and view previously synchronised events during connectivity loss. Open pages receive announcements without manual refresh, and notification use is controlled by user preference. The system remains correct because the durable server feed, rather than the notification channel, is the authoritative record. Learning PointsThe case demonstrates that offline caching, real-time delivery and push notifications solve different problems. A service worker improves availability; SSE reduces update delay; push supports re-engagement. None of these mechanisms independently guarantees data consistency. 8. Testing, Performance and GovernanceTesting should include first installation, service-worker upgrades, cache corruption, private browsing restrictions, offline navigation, slow networks, reconnection, duplicate events, expired subscriptions and multiple browser engines. Automated tests should verify that sensitive responses are not cached and that an old worker does not serve incompatible JavaScript with a new HTML document. Performance evaluation should consider startup time, cache storage, battery impact, event frequency and reconnection behaviour. Real-time updates should be batched or throttled when high-frequency changes do not improve the user experience. Accessibility requires visible status messages, keyboard operation, reduced-motion support and non-colour indicators for connection state. Governance includes data minimisation, retention limits, consent, access control and auditability. Notification subscriptions are personal data in many contexts. Depending on jurisdiction and institutional policy, privacy, electronic communications and data-protection rules may apply. A system should document what is stored locally, how long it is retained and how users can clear it. Contemporary DevelopmentsWebTransport and related protocols may support advanced low-latency scenarios, but they require careful compatibility and operational evaluation. Web Push standards continue to evolve across browsers. Installability, background execution and notification behaviour remain platform-dependent. Consequently, progressive enhancement is essential: the application should remain usable with ordinary HTTPS requests when advanced features are unavailable. Best-Practice Checklist- Use HTTPS and secure WebSocket connections in production.
- Select polling, SSE or WebSockets according to communication direction and reliability needs.
- Treat the server’s durable data store as authoritative.
- Validate, authenticate and authorise every sensitive real-time operation.
- Version service-worker caches and test upgrade paths.
- Never cache private data without an explicit, reviewed policy.
- Provide an offline fallback and show data freshness clearly.
- Queue offline mutations with identifiers and defined retry behaviour.
- Design explicit conflict-resolution rules.
- Request notification permission only after explaining its value.
- Measure reconnects, latency, failures and storage behaviour.
- Provide graceful degradation when browser features are unavailable.
Chapter SummaryReal-time web applications require a deliberate choice among ordinary HTTP, SSE and WebSockets. WebSockets provide bidirectional communication, while SSE offers a simpler server-to-client stream with browser-managed reconnection. Production systems must address authentication, authorisation, ordering, reconnection, scaling and durable recovery. PWAs combine a secure origin, manifest, responsive interface and service worker to deliver installation, reliability and app-like behaviour. Service workers can intercept requests and apply strategies such as cache first, network first and stale while revalidate. Offline-first design stores useful local state, queues mutations and handles synchronisation and conflicts explicitly. Push notifications enable re-engagement but are neither guaranteed delivery nor a replacement for durable business records. Security, privacy, accessibility, performance and progressive enhancement are essential to professional implementation. Key TermsReal-time communication: Exchange of information with sufficiently low delay for an application’s purpose. Polling: Repeated client requests made to check for updated information. Long polling: A request held by the server until an update or timeout occurs. WebSocket: A persistent, bidirectional communication protocol for web clients and servers. SSE: Server-Sent Events, a persistent HTTP-based server-to-client event stream. EventSource: Browser API used to consume SSE streams. PWA: Progressive Web Application enhanced with web capabilities such as installation and offline operation. Web app manifest: JSON metadata describing an application’s identity, icons and launch behaviour. Service worker: Programmable background worker that can intercept requests and manage caches. Cache API: Browser API for storing and retrieving request–response pairs. IndexedDB: Browser database for structured local data. Offline-first: Design approach that treats local operation and intermittent connectivity as normal conditions. Application shell: Minimal interface resources required to start and navigate an application. Cache invalidation: Process of replacing or removing obsolete cached resources. Background Sync: Mechanism for deferring selected operations until connectivity returns. Conflict resolution: Rules for reconciling incompatible local and server changes. Push notification: Server-initiated message presented through a user agent or operating system. Progressive enhancement: Providing a useful baseline experience while adding advanced features when supported. Event sequence number: Ordered identifier used to detect missing or duplicate events. Durable event: An event stored so that it can be recovered and replayed when required. Review QuestionsShort Answer Questions- What is the principal difference between WebSockets and SSE?
- Why does a PWA require a service worker in addition to a manifest for offline operation?
- Define cache-first and network-first strategies.
- Why should push notifications not be treated as proof that a business transaction completed?
- What is the purpose of an event sequence number?
Long Answer Questions- Explain the lifecycle of a service worker and discuss risks associated with immediate activation of a new version.
- Compare polling, long polling, SSE and WebSockets for a live university dashboard.
- Describe an offline-first architecture for an application that allows users to create and edit records.
- Explain the security controls required for a production WebSocket service.
- Discuss how caching, IndexedDB and push notifications contribute different capabilities to a PWA.
Analytical / Application Questions- A monitoring application only sends server-generated temperature updates to browsers. Select an appropriate communication method and justify your decision, including reconnection and missed-update handling.
- Design a cache and data-synchronisation policy for a mobile examination-timetable PWA. Identify which resources may be cached, which must remain network-only and how freshness should be communicated.
- An offline user edits a record that another user changes on the server. Analyse at least two conflict-resolution strategies and recommend one for a university system, explaining the trade-offs.
Multiple Choice Questions with AnswersQuestion 1Which communication method provides native bidirectional messaging between a browser and server? A. WebSocket B. Server-Sent Events C. Cache API D. Web app manifest Correct Answer: A. WebSocket Question 2Which SSE feature can help a server resume a client stream after reconnection? A. The manifest icon B. The Last-Event-ID mechanism C. The Cache API D. The notificationclick event Correct Answer: B. The Last-Event-ID mechanism Question 3What is the primary role of a web app manifest? A. To store structured offline records B. To describe application identity and launch behaviour C. To encrypt WebSocket messages D. To guarantee push delivery Correct Answer: B. To describe application identity and launch behaviour Question 4Which caching strategy prefers fresh network data but uses cached data when the network fails? A. Cache only B. Cache first C. Network first D. Network only Correct Answer: C. Network first Question 5Which technology is generally more appropriate for structured offline records and mutation queues? A. IndexedDB B. The manifest C. EventSource D. TLS Correct Answer: A. IndexedDB Question 6A service worker can directly manipulate which of the following? A. The page DOM B. The browser’s physical display C. Request and response handling D. The user’s operating-system kernel Correct Answer: C. Request and response handling Question 7Why should a real-time client request a snapshot after detecting a sequence gap? A. To install a manifest B. To recover potentially missed state or events C. To remove all user permissions D. To disable HTTPS Correct Answer: B. To recover potentially missed state or events Question 8When should notification permission generally be requested? A. Immediately before any content loads B. After explaining its value during a meaningful user interaction C. Only after deleting the service worker D. Whenever a cache is full Correct Answer: B. After explaining its value during a meaningful user interaction Question 9Which statement about push notifications is correct? A. They guarantee completion of a payment B. They replace the authoritative server database C. They may be delayed or unavailable and should not be treated as transactional proof D. They work without user permission in all browsers Correct Answer: C. They may be delayed or unavailable and should not be treated as transactional proof Question 10Which practice best reduces the risk of serving incompatible cached application versions? A. Never changing cache names or asset versions B. Versioning caches and testing service-worker upgrades C. Caching every private response permanently D. Disabling all network requests Correct Answer: B. Versioning caches and testing service-worker upgrades
|