Awesome Service Workers: a curated collection of resources
When 7 KB Equals 7 MB
While testing a progressive web app for one of our clients, I bumped into a suspicious error in the browser console:
DOMException: Quota exceeded.
After browsing the app a few more times, it became clear the error would occur after a small number of images were added to the cache storage by the service worker. Looking in the Chrome DevTools Application tab, the cache storage was indeed over capacity.

How could this be? There were only ~15 images in the cache storage. Something was off.
What I found could significantly impact your progressive web app—particularly if you use a CDN on a different domain for your assets.
[…]
If you are building a progressive web app and are experiencing bloated cache storage when your service worker caches static assets served from CDNs, make sure the proper CORS response header exists for cross-origin resources, you do not cache opaque responses with your service worker unintentionally, you opt-in cross-origin image assets into CORS mode by adding the
crossorigin
attribute to the<img>
tag.
See the source link for more details.
Source link:
Is service worker ready?
Network based image loading using the Network Information API in Service Worker
Recently, Chromium improved their implementation of
navigator.connection
by adding three new attributes:effectiveType
,downlink
andrtt
.Before that, the available attributes were
downLinkMax
andtype
. With these two attributes you couldn’t really tell if the connection was fast or slow. Thenavigator.connection.type
may tell us a user is using WiFi, but this doesn’t say anything about the real connection speed, as they may be using a hot spot and the connection is in fact 2G.With the addition of effectiveType we are finally able to get the real connection type. There are four different types (slow-2g, 2g, 3g and 4g) and they are described this way by the Web Incubator Community Group:
slow-2g: The network is suited for small transfers only such as text-only pages.
2g: The network is suited for transfers of small images.
3g: The network is suited for transfers of large assets such as high resolution images, audio, and SD video.
4g: The network is suited for HD video, real-time video, etc.Let’s see how we can improve user experience by delivering images based on available connection speed.
Source link:
Send messages when you're back online with Service Workers and Background Sync
This example of using background sync looks like it’s specific to Twilio, but the breakdown of steps is broad enough to apply to many situations:
On the page we need to:
- Register a Service Worker
- Intercept the “submit” event for our message form
- Place the message details into IndexedDB, an in browser database
- Register the Service Worker to receive a “sync” event
Then, in the Service Worker we need to:
- Listen for sync events
- When a sync event is received, retrieve the messages from IndexedDB
- For each message, send a request to our server to send the message
- If the message is sent successfully, then remove the message from IndexedDB
And that’s it.
Source link:
Async events in ServiceWorkers with "event.waitUntil"
It’s asynchronous, see? So even though all that network code appears before the
return
statement, it’s pretty much guaranteed to complete after the cache response has been returned. You can verify this by putting in someconsole.log
statements:
Javascript
caches.match(request)
.then( responseFromCache => {
if (responseFromCache) {
event.waitUntil(
fetch(request)
.then( responseFromFetch => {
console.log('Got a response from the network.');
caches.open(staticCacheName)
.then( cache => {
cache.put(request, responseFromFetch);
});
})
);
console.log('Got a response from the cache.');
return responseFromCache;
}
Those log statements will appear in this order:
Got a response from the cache. Got a response from the network.
That’s the opposite order in which they appear in the code. Everything inside the
event.waitUntil
part is asynchronous.Here’s the catch: this kind of asynchronous
waitUntil
hasn’t landed in all the browsers yet. The code I’ve written will fail.But never fear! Jake has written a polyfill. All I need to do is include that at the start of my
serviceworker.js
file and I’m good to go:
Javascript
// Import Jake's polyfill for async waitUntil
importScripts('/js/async-waituntil.js');