Service Worker: One fallback offline image for any aspect ratio

Written by sebastian.eberlein | Published 2017/08/13
Tech Story Tags: javascript | service-worker | svg

TLDRvia the TL;DR App

Recently, we implemented a Service Worker for an image-heavy website. Since it’s not a good idea to precache every single image and also runtime caching has its limits, we needed a fallback image.

Fortunately, there is an elegant solution that serves a resolution-independent, accessible SVG for image requests that fail. But after we implemented the SVG, we noticed a couple of issues as you can see in this abstract example:

We use lazy loading in combination with intrinsic ratios to minimize reflows, which means that the offline image will not fit the reserved space most of the time. Besides, many image wrappers have a placeholder background color that matches the image. This is especially important if a white text overlays a dark image, since we want to make sure the text is legible while the image is loading.

So we needed a fallback image that works with any aspect ratio and adapts to the existing background color. After some experimenting, we came up with an improved SVG that looks like this:

We used a semi-transparent gray and black as fill-colors, so that any existing placeholder background color is just slightly grayed out and white text on a dark background is still legible.

The most important change is the following attribute:

<svg preserveAspectRatio="xMidYMid slice" ...>

It forces the viewBox to scale uniformly from the center and cover the entire SVG viewport.

SVG code

Codepen

Note: No Service Worker, just the SVG image in the layout from the screenshot above.

https://codepen.io/sebastianeberlein/pen/gxGgXe

In our Service Worker:

Side note: Since Firefox version 47 (released in June 2016), the Accept header of image requests looks like this: */*. So if you are using this header to check if the request is an image …

if (request.headers.get('Accept').indexOf('image') !== -1) {// ...}

… it will work in Chrome, but not in Firefox. That’s why we switched to file extension matching.


Published by HackerNoon on 2017/08/13