Blog

Insights and articles about Web3 development, software engineering, and the latest in technology.

Unlocking Offline Experiences with Service Workers

Unlocking Offline Experiences with Service Workers

<h4>This article will include the following:</h4> <ol> <li>Overview. What are service workers</li> <li>Capabilities</li> <li>Benefits</li> <li>Scope</li> <li>How to register one</li> <li>Service worker Life cycle</li> <li>Use cases</li> </ol> <h4>Overview</h4> <p>Nowadays users expect web apps to start on slow or flaky network connections, or even offline. Google did a <a href="https://www.marketingdive.com/news/google-53-of-mobile-users-abandon-sites-that-take-over-3-seconds-to-load/426070/">study</a> about the percentage of users that will abandon a website if it loads for more than 3 seconds.</p> <p>As developers, our job is to make the user journey as smooth and straight forward as possible. This requires from us to use different tools and techniques to make that possible. One of these tools are service workers.</p> <p>Service workers are a fundamental part of PWAs (Progressive Web Apps) They are background scripts that run independently of the web page, intercepting network requests and caching resources, providing offline capabilities (even when a user has no internet connection a progressive web app can still load and function correctly, as the service worker will serve cached assets). Also, a PWA can load quickly and efficiently, as it doesn’t have to wait for network requests to complete.</p> <figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*z83FJ-X0OAFN8boeX2IURQ.png"></figure><p>However, while service workers provide many benefits, they do require careful planning and implementation; service worker implementation requires special functions and methods. Developers need to ensure that service workers do not interfere with the functionality of the PWA and that they handle updates and errors correctly.</p> <h4>Service worker Capabilities</h4> <p>Service Workers offer a wide range of capabilities that can supercharge your web applications. We’ll delve into key features like caching strategies, background sync, and push notifications. You’ll discover how to leverage these capabilities to create blazing-fast, reliable, and engaging web experiences.</p> <p>Some of the most used capabilities are:</p> <ol> <li> <strong>Offline Support</strong>: Service Workers enable web applications to work offline or in low-network conditions by intercepting and caching network requests and responses. This allows users to access content and functionality even when they are not connected to the internet.</li> <li> <strong>Caching</strong>: Developers can control the caching of assets such as HTML, CSS, JavaScript, images, and other resources. This helps in improving the performance of web apps by serving cached content from the local storage instead of making repeated network requests.</li> <li> <strong>Background Sync:</strong> Service Workers can schedule background sync tasks. This feature is particularly useful for apps that require periodic data synchronization, like email clients or social media apps. It ensures that data is updated in the background, even if the app is not currently open.</li> <li> <strong>Data Background Fetch</strong>: This feature allows web apps to request and process data in the background, enabling scenarios like pre-fetching data to improve user experience.</li> </ol> <h4>Benefits of using service workers</h4> <p>Service workers are easy and straight forward optimization of your web app that we often underestimate. They make it possible to:</p> <ul> <li>Decrease your page load time</li> <li>Implement better caching</li> <li>Give a mobile application like feel to your application, providing functionalities such as home screen icons for mobile browsers, sending push notifications to the user, etc.</li> </ul> <h4>How to register a service worker</h4> <p>The code snippet bellow is checking if service worker property exists on the navigator object, then register the service worker that will be defined in the sw.js file. This tells the browser to register a service worker for the domain the file is being served from and whatever logic exists in the sw.js file is the worker for it.</p> <pre>// your main JavaScript file<br><br>if ('serviceWorker' in navigator) {<br> window.addEventListener('load', function() {<br> navigator.serviceWorker.register('/sw.js').then(function(registration) {<br> // Registration successful<br> console.log('ServiceWorker registration was successful in scope: ', registration.scope);<br> }, function(err) {<br> // Registration failed<br> console.log('ServiceWorker registration failed: ', err);<br> });<br> });<br>}</pre> <h4>Verify if a service worker is registered</h4> <p>We need to open the developer tools in order to verify if a service worker is registered correctly.</p> <p>In Firefox and Chromium-based browsers the process looks like this:</p> <ol> <li>Open developer tools and click the <strong>Application</strong> tab.</li> <li>In the left pane, select <strong>Service Workers</strong>.</li> <li>Check that the service worker’s script URL appears with the status “Activated”. On Firefox the status can be “Running” or “Stopped”.</li> </ol> <p>Once registered the service worker should look something like this:</p> <figure><img alt="Service worker — developer tools on Chrome" src="https://cdn-images-1.medium.com/max/1024/1*sBOqRAaIEeznq2Hyn3aoXg.png"><figcaption>Service worker — developer tools on Chrome</figcaption></figure><h4>Scope</h4> <p>Scope refers to the folder of your service worker. A service worker that lives at example.com/pwa/sw.js can control any navigation at the /<em>pwa</em> path or below, such as example.com/pwa/demo. Service workers can only control items such as pages and workers (collectively "clients") in their scope. Scope applies to browser tabs and PWA windows.</p> <p>Only <em>one</em> service worker per scope is allowed. When active and running, only one instance is typically available no matter how many clients are in memory (such as PWA windows or browser tabs).</p> <p><em>The most common implementation of the service worker intercept all the requests related to your PWA. You should set the scope of your service worker as close to the root of the app as possible. You should not put it inside, for instance, a JavaScript folder or have it loaded from a CDN.</em></p> <h4>Life cycle</h4> <ol> <li>Registration: The first step is to register a Service Worker in your web application. This typically happens in your main JavaScript file or a dedicated service worker file. You use the navigator.serviceWorker.register() method to register a service worker script. The Service Worker script is then downloaded and installed in the background.</li> <li>Installation: After registration, the browser downloads and installs the Service Worker script. During the installation phase, you can specify which resources (e.g., HTML, CSS, JavaScript files) the Service Worker should cache for offline use. This is often done in the install event handler.</li> <li>Activation: Once the Service Worker is successfully installed, it enters the activation phase. During activation, the new Service Worker takes control of any open tabs or windows that are under its scope. This is where you can remove old caches and perform cleanup tasks from previous Service Worker versions. The activate event handler is commonly used for this purpose.</li> <li>Fetch and Intercept: After activation, the Service Worker is active and can intercept network requests made by the web application. This allows you to implement various caching strategies, including cache-first, network-first, or stale-while-revalidate. You handle fetch events in the fetch event listener.</li> <li>Update: If there’s a new version of the Service Worker available (detected during the registration phase), it goes through the installation and activation phases again. However, the new version won’t take control until all tabs using the old Service Worker are closed.</li> <li>Termination: Service Workers can be terminated by the browser when they’re not in use or when the browser is under memory pressure. They can also be manually unregistered.</li> </ol> <h4>Use cases</h4> <p>We could not finish the article without mentioning a couple of use cases:</p> <ol> <li> <strong>Offline analytics</strong> — Capturing telemetry related to users in the web app is highly useful when it comes to user behavior analytics. Typical analytic frameworks require an active connection to send these data to a server. However, with service workers, you can capture user behavior in client side and send it to an analytics engine with background sync. Implementing this by yourself might be a cumbersome task. Google has come up with a tool to support offline analytics named Workbox Google Analytics.</li> <li> <strong>Automatic failovers — </strong>Imagine you have multiple servers to fetch data, and one of your servers is starting to fail. Using service workers, we can quickly implement a fallback mechanism to get data/resources from another server.</li> <li> <strong>Synchronizing data in background — </strong>Service workers can be customized so that when the user performs a post request like edit or update in an app with an unstable connection, it can defer that request and only send it to the server when the connection is stable. The way it does it is in the background through caching and doesn’t affect the offline user experience.</li> </ol> <h4>Conclusion</h4> <p>Service workers are a great way for enhancing the performance, reliability, and engagement of web applications with little effort. By intercepting network requests, caching resources, and providing real-time updates, service workers enable developers to create progressive web apps that can function like native apps.</p> <p>The main concepts that we need to keep in mind when developing a service worker are: <strong>Scope</strong>, <strong>Lifecycle</strong>,<strong> Life span</strong>.</p> <h4>Further reading:</h4> <ol> <li><a href="https://developer.mozilla.org/en-US/docs/Web/API/Service_Worker_API">https://developer.mozilla.org/en-US/docs/Web/API/Service_Worker_API</a></li> <li><a href="https://blog.openreplay.com/a-practical-guide-to-service-workers/">https://blog.openreplay.com/a-practical-guide-to-service-workers/</a></li> <li><a href="https://blog.bitsrc.io/using-service-workers-with-react-27a4c5e2d1a9">https://blog.bitsrc.io/using-service-workers-with-react-27a4c5e2d1a9</a></li> </ol> <img src="https://medium.com/_/stat?event=post.clientViewed&amp;referrerSource=full_rss&amp;postId=5613c6772585" width="1" height="1" alt="">

7 min read