Did you have a situation when website loading takes too much like this gif below?
? Have you heard of service workers?
In this post, we'll dive into what service workers are ?, how they work ⚙️, and how I used them to improve the performance of my web application.
What is a Service Worker? ?
A service worker is a background script that runs separately from the web page, and can:
Key Characteristics of Service Workers:
Here's a simple example of Service Worker script:
if ('serviceWorker' in navigator) { window.addEventListener('load', function() { navigator.serviceWorker.register('/service-worker.js').then(function(registration) { console.log('Service Worker registered with scope:', registration.scope); }).catch(function(error) { console.error('Service Worker registration failed:', error); }); }); }
? In this snippet, the service worker (service-worker.js) is registered when the page loads. If the registration is successful, it logs the service worker’s scope; otherwise, it logs an error.
I was integrating a Unity WebGL game into a .NET Razor website. The game consisted of large ".wasm" and ".data" files alongside JavaScript files that were crucial for the game to load. However, the first time the page loaded, it took over 20 seconds! ? This was primarily due to the size of the ".wasm" and ".data" files.
I created a "ServiceWorker.js" file, which caches all the necessary game assets to reduce the loading time. Here’s what the file contains:
const cacheName = "$Project_name"; const contentToCache = [ "Build/Game.loader.js", "Build/Game.framework.js", "Build/Game.data", "Build/Game.wasm", "TemplateData/game_style.css" ]; self.addEventListener('install', function (e) { console.log('[Service Worker] Install'); e.waitUntil((async function () { try { const cache = await caches.open(cacheName); console.log('[Service Worker] Caching all: app shell and content'); for (const resource of contentToCache) { try { await cache.add(resource); } catch (error) { console.error(`[Service Worker] Failed to cache: ${resource}`, error); } } } catch (error) { console.error('[Service Worker] Failed to open cache', error); } })()); }); self.addEventListener('fetch', function (e) { e.respondWith((async function () { try { const response = await caches.match(e.request); console.log(`[Service Worker] Fetching resource: ${e.request.url}`); if (response) return response; const fetchResponse = await fetch(e.request); const cache = await caches.open(cacheName); console.log(`[Service Worker] Caching new resource: ${e.request.url}`); await cache.put(e.request, fetchResponse.clone()); return fetchResponse; } catch (error) { console.error(`[Service Worker] Error fetching resource: ${e.request.url}`, error); throw error; } })()); });
What does this code do?
This service worker script performs the following actions:
By caching these assets, the loading time was reduced from 20 seconds to under 3 seconds ?. The next time users visit the page, the assets are already stored locally, drastically speeding up the experience.
While this approach works wonders for improving performance, it introduced another issue: outdated cached files. Since we're actively developing the Unity game and releasing new versions, the cached files needed to be cleared every time a new version was deployed.
To solve this, I created a pipeline script that automatically unregisters the old service worker and clears the cache whenever we publish a new game build. This ensures that users always load the latest assets without being stuck with old, cached versions.
Implementing service workers in your web application can dramatically improve performance, especially when dealing with large assets like in my Unity WebGL game. However, it’s important to handle caching carefully to avoid serving outdated files.
Have you had similar experiences optimizing load times? Did you use service workers or other techniques? Share your thoughts and insights in the comments below! ?
Hope you learned something new today! ✌️
Disclaimer: All resources provided are partly from the Internet. If there is any infringement of your copyright or other rights and interests, please explain the detailed reasons and provide proof of copyright or rights and interests and then send it to the email: [email protected] We will handle it for you as soon as possible.
Copyright© 2022 湘ICP备2022001581号-3