Push real-time data to Progressive Web Apps (PWA)

Progressive Web Apps (PWAs) are web applications that use the features of modern browsers to offer a native-app-like experience on every platform. They rest on three pillars: responsiveness, reliability, and installability.

PWAs are responsive because they render well on a variety of devices and window sizes to ensure usability and user satisfaction.

PWAs are reliable because they are usable regardless of network connection.

PWAs are installable because they can be added to the user’s home screen, dock, or taskbar. It is possible to search for them on a device and jump between them with the app switcher like native apps.

In more and more scenarios, PWAs are replacing native mobile apps and hybrid apps, to save on development and maintenance costs, while enlarging the compatibility with the broad base of client-side platforms.

There are many uses cases where applications need to receive real-time data, pushed by a server over a streaming channel: online trading platform in the financial brokerage space, monitoring dashboards, second-screen applications, group chats, betting solutions, and many more.

Is it easy to push live data to a PWA? The short answer is yes if you use a modern streaming engine like Lightstreamer.

Lightstreamer is a message broker optimized for the web. It powers event-driven architectures (EDA) by delivering real-time messages and events across the firewall boundaries, taking into account Internet unpredictability and packet loss.

To demonstrate how easy it is to develop real-time PWAs, we transformed a standard web app into a PWA. Specifically, we reimplemented our famous Basic Stock-List Demo, which shows ten stocks dynamically updated by a random simulator and sent in real time to the web client by the Lightstreamer Server.

You can check out the result here: https://demos.lightstreamer.com/PWAStockListDemo/

PWA Demo

The first step is to add a manifest to the app. A manifest is a JSON file that tells the browser about your PWA. Typically it includes the app name, the icons the app should use, and the URL that should be opened when the app is launched.

In the case of our demo, the manifest looks like this:

{
    "short_name": "Lightstreamer PWA Stock-List Demo",
    "icons": [
        {
          "src": "images/icon196x196.png",
          "type": "image/png",
          "sizes": "196x196"
        },
        {
            "src": "images/icon1024x1024.png",
            "type": "image/png",
            "sizes": "1024x1024"
          }
    ],
    "start_url": "/PWAStockListDemo/?source=pwa",
    "display": "standalone"
}

The second step is to add a service worker, a script that is responsible for downloading the app’s files, saving them into a cache, and later serving them when needed. Since the service worker can fetch the resources from the network or from the local cache, the app is available even if the user’s device is offline.

In our app, we chose a simple cache policy: we serve the cached page offline.html when the fetch from the network fails, as the following snippet shows:

self.addEventListener('fetch', function(event) {
  //console.log('[Service Worker] Fetch', event.request.url);
  if (event.request.mode === 'navigate') {
    event.respondWith((async () => {
      try {
        const preloadResponse = await event.preloadResponse;
        if (preloadResponse) {
          return preloadResponse;
        }
        const networkResponse = await fetch(event.request);
        return networkResponse;
      } catch (error) {
        console.log('[Service Worker] Fetch failed; returning offline page instead.', error);
        const cache = await caches.open(CACHE_NAME);
        const cachedResponse = await cache.match(OFFLINE_URL);
        return cachedResponse;
      }
    })());
  }
});

Progressive Web Applications is a vast subject and we’ve only scratched the surface. If you want to know more check out the live demo and the complete source code on GitHub.

July 19, 2024
Originally published: November 11, 2021


3 min read