Progressive Web Applications is one of the hottest trends in Web Development right now, with more and more people willing to learn about the concept and technology. Most of the articles on this topic are either very low-level and difficult to devour for non-technical people or, on the opposite, very brief and shallow. In this blog post we tried to achieve the impossible - explain the concept behind PWA in a way that would be engaging and understandable not only for IT-professionals but also for those that are generally interested in what’s new and hot in the web industry today.
How Progressive Web Apps make the Web great again
Being progressive is tough.
You have to constantly keep up with the ever-changing world outside and be well aware of new trends in art, fashion, politics, health and food. You should be able to tell Trump from Obama. Know that Manet and Monet are not the same guy, even though both used to paint stuff. Cook like Jamie Oliver (or at least pretend to be cooking while randomly throwing food around your kitchen). Ditch burgers and kebab in favour of green leaves of unknown origin that even cows refuse to eat. Drink smoothies made of the same leaves while trying your best not to throw up.
Being progressive in the IT business is even harder. In addition to everything mentioned above you should be able to program in all popular JavaScript frameworks, own 50 T-shirts of every shade of grey, recognise each Pokemon by name and not confuse IPA and APA with SPA. Growing a beard will give you extra points in progressiveness (double points if you’re a girl).
If you’re not a 90-year old farmer from Texas then I bet you own a smartphone. Look at it - these colourful squares on its Home screen are called “native apps”. They are called “native” because they are developed natively for the operating system of your smartphone (be it iOS or Android or - god forbid - Windows Phone).
If you are a web developer then most likely you build websites. But websites are soooo ‘90s, it’s all about apps nowadays. And, being a progressive web developer, you obviously cannot just develop mobile apps ‘cause, well, mobile apps are sooo ‘00s. So, it was just a matter of time before the concept of Progressive Web Apps was born.
Development of mobile apps have always been this “forbidden area” which a few of us, web developers, dared to step into. You would have to be a hardcore backend programmer with knowledge of Objective-C, Java or C++ or, more recently, frameworks like Xamarin or Cordova that allow developers to target multiple mobile platforms with one codebase. And then, of course, there’s always a pain of making your app public (if you ever tried to deploy your app to AppStore, you would know) and keeping the website and all of the mobile versions in sync with each other.
Obviously, web developers were not happy with this situation. They grumbled relentlessly from the cellars of their parents’ houses, some even swore to quit drinking Coke and eating chips until the problem is solved. One reckless soul even went as far as promising to wash his gaming T-shirt but came to his senses before it was too late. Meanwhile, many bright minds tried hard to eliminate the irritating gap between the web and mobile development, until finally in 2015 Google introduced their next best idea after the Chrome’s Incognito Tab - the concept of Progressive Web Apps.
What are Progressive Web Apps?
The concept is brilliant in its courageous simplicity. You develop a website which looks and behaves exactly like a native mobile app, which means that it can be added to the home screen on a smartphone, send push notifications, access the device’s hardware and - most importantly - work offline. Yes, you heard it right - Progressive Web App works just as smooth on a shaky or no network as it would with full internet access.
But… but… how can a browser open a website without being able to access it on the web, you may ask? Well, believe it or not, but your browser is now capable of many interesting features which you’d never expect it to be just a couple of years ago, unless of course you’re a proud and dedicated user of Netscape or Internet Explorer 6.
Sites like whatwebcando.today are able to analyse your browser’s APIs and show which of the features natively available on mobile devices are also supported by your browser. Give it a try - I bet you will be surprised. My current version of Chrome (56) supports 33 out of 36 features and the rest are being worked on.
‘Ok’, you think, ‘so my browser supports all these features - fine. But I have so many apps on my smartphone which I use every day, I cannot just drop all these and switch to web apps”. But you are probably mistaken here as well.
A research conducted in 2015 by marketingland.com shows amazing statistics:
Mobile users spend 80% of the time
on their devices using only their top three apps
It shows that there’s a very high chance that a funny app you downloaded 5 years ago to draw moustache on a photo of your mother-in-law most likely hasn’t been used ever since. Most of us are using just a handful of apps, like Facebook, Instagram, Pinterest, a mail reader, some weather app and that’s about it. And - surprise! - most of those can also function as web apps while being much lighter in size.
Another huge disadvantage of mobile apps is their discoverability. To download an app from a store you must first of all find it there (which means you have to know exactly what you are looking for, otherwise you’ll have to crawl through tons of featured crap), click “Download”, confirm, agree to terms, enter your password, wait for the app to download, wait for it to install bla-bla-bla… By the time it’s all over you might easily forget what was that you were looking for to begin with.
According to Gabor Csele, a Product Manager in Google, in a mobile app every step you make a user perform before they get value out of your app will cost you 20% of users.
The chart on the left compares how long it takes a user from the moment he discovered an app to the moment he actually opens it, on the web and a mobile. The difference is 40 seconds and that is a darn long time on the internet scale. Beauty of a web app is that it’s extremely discoverable, just like a regular website - you google it, you click the link to open it and that’s it, you have the app on your device, ready to roll.
It's hard to believe but in just one year from May ’15 to May ’16 downloads of mobile applications in the US declined more than 20%.
If we look at the statistics per user, it's even funnier. According to a report from comScore, in the UK more than a half of smartphone users download ZERO apps every month. In the US it's worse - almost 66%.
Ok, let’s assume I convinced you that mobile apps were doomed and now you are anxious to learn this new progressive stuff to be on top of the game when web apps completely conquer the mobile world. The main thing to understand is that “Progressive Web Apps” is not a technology or a framework or a programming language. It’s more like a set of requirements your web application must meet to properly function as progressive. There are some new things to master in process, but nothing complicated.
Let’s take a look at how exactly a PWA manages to function as a native mobile app.
Caching of App Shell
App Shell is, well, a shell of your application. It’s the minimal set of HTML, CSS and Javascript required to render the main page of your application. When you go online and open a web site, you wait for the entire main page to download, and that includes not only dynamic content of the page but also all of the images, fonts, stylesheets, JavaScript used on the page - and most of these remain the same no matter how many times you open the site. So why not cache the whole thing?
When a PWA is launched for the first time it immediately puts all of the static resources its app shell is built off into the cache. The next time the app is launched, it will serve all of the static assets directly from the cache, dramatically improving the time it takes before user sees precious pixels on the screen. If you ever tried to open a website on a 3G connection, you’ll know what I mean.
Caching of responses
This is arguably the most powerful thing PWAs are capable of. They can cache not only static components of the App Shell but also entire responses from GET-requests.
Let’s say, you visited a news web app yesterday to browse and read some news. If you open it today, you will instantly get yesterday’s newsfeed on your screen while the app is fetching new content in the background, dynamically embedding it inside the feed you are already looking at. If fresh content cannot be fetched, for example because you are offline, then you will stay with yesterday’s feed but at least you won’t get any errors or endless spinners rendering the entire app useless.
There are several caching algorithms you can implement and it’s up to you which one to go for depending on the purpose of your app. These are the main ones:
- Use “Cache with fallback to Network” if you are building an offline first application. If response is already in the cache, it will be served to the user and online request will never be made. If response is not cached yet, the app will try to fetch it online and then put it in the cache. This approach should be used for content that changes very rarely or doesn’t change at all.
- “Network with fallback to Cache” is an approach where online users always get the up-to-date online version while offline users get cached version. Use it for resources that are frequently updated.
- “Cache and Network race” is when you simultaneously look for response in the cache while requesting online content at the same time. You show user cached response first and then replace it with fresh content once it arrives, or append new content on top of the cached like Facebook and Twitter do.
No matter which pattern you use, you should always handle the case when response is neither cached nor can be fetched online. In this case you should serve a static HTML page (which should also be cached as a part of the App Shell) which will say something graceful to calm down the user, like “Sorry, dude, your cache is empty and internet is down - go get a normal life”. This is a nice way to let the user know that something went wrong and there’s no way to serve this specific content at the moment. This will make your app 100% failproof and make it function even during apocalypse.
Web Application Manifest
Offline support is extremely important, but in order to successfully replace a native app your PWA must also look and behave like one. This is achieved with a file called manifest.json which contains JSON-formatted properties of your application, like name, url of the main page, icons for different device resolutions, colors of the splash screen, device orientation, whether browser controls are visible or not etc.
If you open the app twice on your mobile device (only Android for now) with at least 5 minutes between the visits, you will be prompted to install it on the device (assuming your manifest is in place, of course). If you agree to that, you will see your app's icon on the home screen of your device, residing peacefully side by side with the native apps. Now you can launch your PWA just like you would a mobile app - with a nice splash screen, orientation recognition, access to mobile hardware etc. You should of course make sure your PWA is using native-app-like design and especially navigation, I recommend using one of the Material Design UI component libraries.
Service Worker
We’ve gotten this far in an article dedicated to Progressive Web Apps without even mentioning a Service Worker - wow! All of the caching we just talked about is performed by a browser's little helper called "Service Worker", which is basically nothing else than a JavaScript file residing in your app but running in a separate process, which means that it won’t be terminated when you close the app in your browser (or even the browser itself). Once registered from the app’s main page, the Service Worker should immediately cache static assets of the App Shell and start listening to requests sent by the app, caching and serving responses based on the logic you programmed in it.
The Service Worker doesn’t have access to the DOM - so don’t even try that - but it does have access to all of the Web APIs and that’s where its power lies. In addition to caching, it can send notifications, push messages, synchronise local cache with remote data storage in the background, it can even mock responses with dynamically created content if you program it to.
The Service Worker will continue living in your browser until you explicitly terminate it from the browser’s Developer Console, or make changes to it, in which case it will update itself to the new version. This is very useful when keeping your app always up-to-date, and is a major advantage compared to mobile apps which you have to remember to update.
Are we there yet?
So, is everything so clear and peaceful in the PWA heaven? Not exactly.
First of all, the concept is relatively new and service workers are not yet supported by all browsers. The biggest bottleneck here is lack of support from Apple who apparently see the rise of Progressive Web Apps as imminent threat to the AppStore. At the moment of writing, both Service Workers and Web App Manifest are still “Under Consideration”. Luckily, considering fantastic support of PWAs on Android devices and positive response from all the major browser vendors, Apple doesn’t have a choice other than eventually implement support in iOS.
Secondly, even those browsers that already embraced SW have various level of support when it comes to Web APIs (as showcased by whatwebcando.today), so you should be extra careful when developing a super-ultra-cool PWA that accesses bluetooth or microphone, if you need cross-browser support of course.
On top of that, developing a service worker is not very straightforward (and debugging is a real nightmare). You should be a quite experienced developer in order to build a relatively complicated Progressive Web App. Service Workers’ lifecycle is a bit cumbersome and the script itself is promise based, so make sure you use asynchronous APIs to not block the page execution.
Useful resources
There are many great and useful examples out in the Web, which is one of the reasons I tried to stay away from code snippets in this article. Here's just a few to help you kickstart your amazing journey towards the future of the Web:
- Fantastic article by Jake Archibald explaining in details all aspects of Service Worker’s caching, with code snippets and examples.
- A multi-section DIY-article from Google to build your first PWA.
- Open-source sample PWAs from Google.
- An entertaining selection of real-life Progressive Web Apps, ranging from simple currency converters to complex e-commerce shops and newspaper agencies.
- Starter toolkits that help you build an app from scratch. Some of them include a package builder, web server or UI component library. Some of them can even generate code for the service worker for you.
- Last but not least, a super useful Chrome extension called Lighthouse which performs audit of your app to check how well it meets requirements to a Progressive Web App, and gives you total score as well as tips on how to fix things your web app scores low at.
Conclusion
The Dawn of the Planet of Web Apps is upon us and we are lucky inhabitants of this planet, witnessing merge of the two huge worlds - Web and Mobile. The result will definitely be nothing short of spectacular: web developers will finally be able to quickly create and deploy applications that look and function equally great on all platforms, while app users will get instant access to their favourite web resources in the form of mobile apps, but better performing, smaller in size, instantly discoverable and always up-to-date.
Congratulations! Now you are fully capable of having a PWA-dedicated chat which will surely make you a star of any cocktail party and an ultimate chick magnet, so go get ‘em!