Going offline with Progressive App Development #2


Going offline with Progressive App Development #2

This is the second post of the series “Going offline with Progressive Web Apps”

In the previous post, we showed an approach to offer offline support to a progressive app development, using Service Workers (SW).

This time we are going to cover other interesting aspects of an offline application, such as the web manifest and how to handle requests while offline (say Google Analytics or other API calls).

Nowadays, Service Workers are supported only in Chrome, Firefox and Opera. Therefore in this post we will cover how to use the application cache in those browsers without SW support during the progressive app development. This way we can ensure offline support for most of the browsers.


Application Cache: an alternative to cache resources

If we want our webapp to have offline support, it should be for every (or most) devices, not just for those with the latest technology. That’s part of being progressive. Fortunately, as recommended by Patrick Kettner, we can use appcache which is available in most browsers, including Safari and IE.

This technology is deprecated in favor of SW, but it will allow us to view our site when offline. It needs a manifest to tell the browser what files need to be cached. Once again, we can manually create the file following the docs, or generate it using a tool like appcache-manifest.

This command will generate it for us:

However, the problem with the appcache API is it must be declared in the html tag at load time, it cannot be injected dynamically.

What this means is, if Service Workers are available and the appcache is always used, then we will end up having all the resources twice. In order to avoid this, we can dynamically create an iframe which loads an html that only references the manifest file (only when SW are not supported):

Also, we need to add a condition to our registration code, in order to load the iframe:

Having that, we can check in Safari how it looks. There isn’t a Service Worker section, but an Application Cache section:

Progressive app development

In addition, if you check that in Chrome, the application cache should be empty.


Have you seen our previous post about Progressive Web Apps?
In the first post we covered the basics of Service Workers. If you are curious about it, take a look at the link!


Web manifest

Web Apps can be added to the home screen of your device. This is how you could install a web app, and you can control some aspects of it using a web manifest file. This is just a JSON file that can be created manually following the specs.

The following image shows how to add a webapp to the home screen in iOS and Android:

Take a look at our Progressive Web App, the UX Quiz.

As we didn’t want to create that file manually, we decided to automatically generate it, at least as a starting point, with a tool like manifestation. This tool generates the manifest by extracting the information of the webapp itself. So running it in the current version of the web app, we got an acceptable manifest.json.

Chrome DevTools has a section to display the file, and even warns you about problems in it:

Progressive app development

If you are thinking about to create an offline app, I encourage you to look at the web manifest specs. There you define the icons of your site (it will be the icon on the home screen), name, description and more during your progressive app development.

One of my favorites is the property display. By default it’s set to browser, but if we set it to standalone, when we open the app, the url bar won’t show up!

This is a pretty simple step, but will make our webapp more appealing.


Google Analytics

During the progressive app development, some questions come up like what happens to the analytics tracking. Ideally we shouldn’t lose that information, and fortunately there’s a Google helper called sw-offline-google-analytics that records all the failed tracking events, and retries them whenever the connection is back.

This tool works by trying to send a request to Google. If it fails then the request is stored in IndexedDB. Next time it succeeds, all the previous failed requests will be retried (and removed from the IndexedDB).

As you can guess, it runs inside the Service Worker, intercepting requests to Google Analytics.

It is not a good idea to manually edit the service-worker.js file, because it’s automatically generated. What we can do is add the script files to the sw-precache configuration (sw-precache-config.js):

The first imported file belongs to the sw-offline-google-analytics component itself. The second one just calls a function within that file to initialize the component.

This way, we are adding behavior to our service worker, without modifying the generated file.

Notice that this solution does not work with Application Cache. If you have a solution, we would love to hear it!


Splash Screen

Android devices will display a splash screen when opening the app, which is generated from the web manifest. It will appear as just a screen with the appropriate background color and the icon (both taken from the web manifest).

Here’s an example of the splash screen of our app, using the theme color and one of the icons:

Progressive app development

Also, it’s possible to do the same for iOS, but in this case you will need some meta tags.


Posting results

The approach of the sw-offline-google-analytics tool implies that nothing will be resent until a new event is successfully tracked. In other words, there has to be more user interaction in order to replay the requests.

What if the user doesn’t do that? Well, we would never track those events. It doesn’t seem too bad for Google Analytics tracking, but it is if we are talking about retrying API calls.

That’s where Background sync comes in handy. Because it allows us to run some code as soon as the user has connectivity (if the user is connected, it will run immediately). Unfortunately, at the time of writing, Background sync is only supported in Chrome.


tl;dr: progressive app development

To sum up, we looked at how to manage the progressive web application, using Service Workers when available and using the Application Cache as a fallback. With SW it’s simple to keep track of the failed requests and replay them later (just like we did with the Google Analytics tracking), but if we want to do the same thing using appcache, things get trickier.

As a result, when designing the application to work offline, we know that in the worst case we will be able to render the page (the browser at least supports app cache), even when some features won’t work (such as the analytics tracking).

It’s a trade off. So, in our case, rendering the web is far more important than the tracking.

During these posts, we showed you how to start to build your offline web app, and how to solve common problems. Also, there are more things to try, like adding a splash screen for iOS, using background sync, etc.

We hope this has been useful for you! If you haven’t checked our PWA yet, take a look at it over here.



Share on FacebookGoogle+Tweet about this on TwitterShare on LinkedIn
Matias Delgado

Matias Delgado

I am a Software Engineer with 11 years of working experience. My main area of experience has been web development. I have worked in domains such as real estate, legal advice, banking services, automotive spares sale, telecommunications and others. My passion is to work as a JS developer, with focus on the user experience and code quality. I co-organize the Angular Meetup community in Montevideo, Uruguay, where I am a regular speaker.

Thanks for signing up!

Stay Connected

Receive great content about building successful products!