You’ve Come a Long Way, Baby
Technology comes in cycles.
In the early days of smartphones, the best (and perhaps only) choice for mobile applications was native code – writing in the language and using the APIs provided by the phone’s Operating System. Then HTML5 and WebView looked like the future, but as Facebook found (to their chagrin), it couldn’t exhibit the fluidity and interaction behaviours that we’ve come to love on our phones.
So we wrote native apps again.
Hybrid apps (e.g. React Native) or compile to Native (e.g. Xamarin and Flutter) are currently very popular. Still, there’s been some push back recently regarding the difficulty in debugging a transpiled language, or one in which code execution is passed between multiple contexts (e.g. AirBNB dropping React Native Support).
If you can afford it, you write native.
In all this time, web technologies have been slowly adding capability and support for the modern, mobile environment on which it is run. These features are often bundled together and called a Progressive Web Application (PWA).
Wikipedia describes a PWA as:
Progressive Web Apps (PWAs) are web applications that load like regular web pages or websites but can offer the user functionality such as working offline, push notifications, and device hardware access traditionally available only to native mobile applications. PWAs are an emerging technology that combine the open standards of the web offered by modern browsers to provide benefits of a rich mobile experience.
It’s definitely not a panacea for all of your mobile application requirements. It does provide a well supported, carefully controlled and well established common platform for single development across all devices and form-factors. Native applications are under no threat for performance heavy applications. However, with a little bit of upfront thinking (and perhaps a little compromise) you can develop cross-platform apps that are easier to write, easier to maintain, easier to deploy and better supported than any of the solutions available. Not for all types of application, but perhaps a larger subset than is immediately obvious.
Don’t Be Evil
Google gets a lot of flak these days for being just another Evil Big Tech Company. Not without some justification – Google have a dubious history of illicit data collection, supporting state-sponsored censorship and other moral misdemeanours. However, it is worth noting that the work they do in pushing web standards forward is unparalleled. With the possible exception of Mozilla, no other company make anything like the same investment – even when it seems like it may be at odds with some of their existing income streams.
Apple has been accused of dragging its feet when implementing PWA technologies. It would no doubt reduce the number of apps that need to be downloaded and controlled via it’s App Store. No money will flow into Apple’s coffers if someone downloads a free PWA and makes in-app purchases, cutting off their handsome 30% fee.
Google, with their Play Store, have the same revenue model. Yet they are driving the PWA standards as hard as they can. Chrome on the desktop and on Android offers the most complete support of the various standards, whereas Apple either have critical gaps or “interesting” implementations that definitely handicap the PWA’s range of functionality.
Despite all of Apple’s reluctant conformance with the latest web standards, progress is being made. Let’s take a look at what you can now achieve…
What Can We Do With a PWA?
Note: Stated support of the various features is assuming the latest versions of operating systems and browsers at the time of writing.
Offline Support is the key enabling technology for PWAs, provided by a Service Worker. A Service Worker is able to intercept network requests from your web site (e.g. when fetching an image from the server) and determine how to fulfil them. If it already has a matching resource it can return that from the local cache and save the long round trip over the internet.
It can do the same thing for API requests, and is able to support different caching strategies. For example, with API requests it is preferable to fetch from the cache only if the application is offline under most circumstances.
Service Worker caching is where we start to see some discrepancies between Google and Apple in their implementations. The Service Worker specification, and Chrome, support Background Sync – the ability to synchronise any offline data when a connection is available without interaction required from the user. Microsoft Edge and Firefox are currently in development with this feature. Apple’s Safari browser does not, and looks unlikely to do so in the foreseeable future.
The amount of data we can save for offline usage also varies. Most browsers support “up to” 2Gb of data per domain – though it depends on the size and free space of the disk. If you only have an 8Gb disk, you’re only likely to get about 20Mb. With Safari on an iOS device, you’ll never be allowed more than 50Mb. This is enough for most normal web applications, but woefully short if you are hoping to provide an offline cache of photos, captured videos, or map base-tiles.
Apple’s current policy is to remove unused Service Workers and caches after “a few weeks”. Maybe this seems reasonable, but it would indicate that the Background Sync, and Push Notifications (see below) are not priorities either.
Save To Desktop
PWAs can be saved to the desktop of your device; looking and behaving like a normal, native app. Using a Web App Manifest file allows you to specify the page that will be loaded when the user clicks on the icon, and how state should be preserved if the user closes and reopens the app.
Apple’s implementation on mobile Safari is closer this time, though still lacking a few features. It ignores the Manifest’s instructions to open in a specified device orientation, uses a non-standard link for the app icon, does not support splash screens, and a few other minor frustrations. Perhaps most significantly, application state is lost when re-opening from the icon on the Home Screen. If the user was in the middle of an action, switched to another application and then re-opened the PWA from the icon on the home screen, then they would be returned to the entry page.
On the whole though, not a bad showing from Cupertino on this one, but once again showing they don’t quite care enough about user experience on this technology to smooth the rough edges.
Push Notifications allow messages to be pushed from the server to client. Due to Service Worker support, this should be possible even when the site is not currently open in the browser.
Unfortunately, support for this is really limited to Firefox and Chrome. Safari desktop has it’s own entirely custom implementation, but iOS Safari doesn’t even have that. It’s clear that Apple is in no rush to implement this feature, and their decision to unregister Service Workers after a period of time leads to the conclusion that they don’t see it as a valid strategic direction.
Push Notifications are an ‘icing on the cake’ PWA feature anyway, so their lack of cross vendor support is no fatal blow. It is, however, annoying and indicative of Apple’s begrudging adoption of these new standards.
The HTML5 Geolocation API allows the web application to determine the user’s location from wi-fi and, if the device supports it, GPS look-up. As with many of the technologies that fall under the PWA umbrella, the user will be prompted to grant permission the first time a location is required.
Documented support for Geolocation looks strong across all browsers and platforms, with Microsoft Edge being the stand-out exception. Given the low usage of this browser on mobile, this won’t be of any concern to PWA developers.
Sensors (Magnetometer, Accelerometer, Gyroscope)
Access to the phone’s orientation and motion has been available for some time on Chrome and iOS Safari. Fair enough that it’s not supported on desktop Safari; the use-case of waving your laptop around to pull out some motion data has to be fairly niche.
It’s a complimentary technology. Reasonably useless on its own, but when combined with other functionality it adds a new dimension onto what is possible. The existing Device Orientation and Motion API is enough to tell you, for instance, which direction the phone is pointing when a photograph is taken. Coupled with a GPS location, this gives excellent data for use in monitoring scenarios.
The same orientation and motion data could, in theory, be used to support Augmented Reality. Knowing where you are and what direction the camera is pointing will allow the phone to render items (hazards, information, Pokémon…) in your field of view. In practice, following on from some research carried out here at Media Suite Towers, the variability of data provided by the sensors makes for very tricky real-time calculations of what to overlay on the image.
There are some cross-browser inconsistencies in this existing API; differing coordinate systems are the big one. Partly to address that, and also to have a more generic-cross sensor API, Google is proposing a new API. This has hardly any support right now, so we’ll have to wait a little longer for a unified and consistent future of sensor data.
The differing coordinate systems are not a deal breaker, and the existing widely supported APIs are good enough for now to make some interesting applications. You’d probably have to re-write a chunk of code in a few years, but given the speed of development in this space – both on the web and in native applications – that is pretty likely regardless of what you’d like to achieve.
Camera and Audio
Access to the camera and audio is now possible across the whole range of browsers, and it’s pretty exciting. Recording a whole video, or capturing a single frame, adding it to an HTML canvas and marking up the image are now all perfectly possible.
Unfortunately Apple step up again here with possibly their worst miss in this gamut of technologies. Once a PWA is added to the homescreen it stops running in Safari and instead runs inside an iOS WebView. The WebView technology is older, more integrated with the OS and does not share data (such as a cookies) with Safari. WebView also does not support the navigator.mediaDevices.getUserMedia API at all.
What this means is, once the user has ‘Added to Homepage’ on an iDevice, they can no longer access their phone’s audio or cameras. If they only access from Safari, or the app author mandates in the Manifest to open in Safari, then everything works fine. What both of these solutions mean however, is that the user loses that lovely ‘feels like an app’ experience that a PWA should ordinarily be able to provide.
Are PWAs For You?
On Android devices, you can write a PWA that will have very close feature parity with native apps, with exceptions around touch interactions, animation smoothness* and cache size. Apple is still letting us down however. While rudimentary caching and functionality is present, the killer features of a PWA only really become apparent when you start to join everything together into a combinatory experience.
Building native, or even hybrid, applications can be frustrating. Managing each type of device’s quirks is incredibly difficult to entirely abstract away, though this is exactly what browsers have been doing for over 20 years. Deployment to the Play Store or App Store is an exercise in arbitrarily applied pain – especially for Apple where it seems the terms and conditions around what the app needs to do, or not do, to be successfully submitted to the App Store is a silently moving set of goal posts.
PWAs remove these frustrations entirely – it’s true write-once-deploy-anywhere, the Holy Grail of application development. Any device, mobile or desktop, can use some or all of the PWA feature-set for far cheaper build and maintenance costs.
While Apple’s casual disregard for web standards continue, it seems that PWAs will not be killing off the App Store just yet. However, where a quick prototype is needed, or if you can be sure that your users will be primarily using Chrome, then I’d reach for a PWA first every time.
- Native applications get a separate thread to handle animations, and web technologies don’t yet have that option. As result, animation can be a little janky if happening alongside other thread blocking activities.