The growth in global internet usage is continuing - Now around 50% of internet users are accessing web apps
Multi-platform users (those who access online content via desktop and smartphone / tablet in a month) remain the majority overall, with an average across markets of 46% of the total population.
Mobile only usage now averages just above desktop only consumption with a cross-market average of 30%, driven heavily by large share in APAC markets, versus 24% for desktop only.
As you can see – there is no desktop native, As desktop web is enhanced and capable as native desktop apps.
Mobile apps have a higher concentration of time spent in the top 10 and a significantly smaller long-tail than desktop and mobile web
One way to think of the differences between native and web apps is on the capability - native apps have the ability to start up reliably when you tap their icon. They boot up quickly, they tend to work offline (who here has opened a web browser to use a web app when they KNOW their device is offline?), they can send push notifications, and sync in the background, they have access to sensors like microphone and camera...by contrast, the Web is safer, and more respectful of privacy, but doesn't have those capabilities, does it? Instead the web excels in reaching users.
According to a recent comScore study, A majority share of smartphone users don’t download any apps in a month, and the average user downloads two
App discovery is down across several channels, including the app store, word-of-mouth and advertising. Is interest in new apps waning?
By contrast, mobile users visit over 100 web sites per month. This is the power of URLs and the ephemerality of the web. They meet one-off needs.
So what if we could add the capabilities we need, and the web could meet those UX expectations? We could have the best of both worlds.
This is what Progressive Web Apps represent - a user experience good enough, integrated enough, to earn a place on the home screen and in the notification tray, without having to give up reach to get it.
In order to do that, we need to focus on four things. Making the web FAST. Making experiences more INTEGRATED. Ensuring that they are RELIABLE. And keeping users ENGAGED. Let’s take a look at each of these properties in a little more depth.
Users don’t expect janky scrolling or slow load performance. The web has a bad name for slow performance, particularly on mobile; although in-page performance isn’t my focus today, that’s fixable. But Fast also means fast loading - supporting the reliable point; loading an app has to be invisible.
We all know time is money. This data from SOATSA shows just how much that's true. After only a little more than three seconds, 20% of your users have abandoned the experience
Users shouldn’t always have to reach through a browser tab to access your app. In fact, the user shouldn’t even think about the fact that they’re on the web, just that they’re using the phone, tablet or desktop to complete the task.
Users should be able to interact with your app in the same way that they do all other apps on their device.
They expect to launch it from the same place they launch all of their other apps. They expect to see it in the task list. They expect it to have all of the capabilities and hardware access that other apps have.
Web Payments - something we’ll cover in a bit more depth later - is a good example of keeping a user in your flow, while using some interesting device functionality to complete a payment. Instead of requiring the user to fill out a complex checkout form, the Payment Request API simplifies it down to a few taps, and can even integrate with other payment apps on the users device like PayPal or Android.
Web payments - is a good example of keeping a user in your flow, while using some interesting device functionality to complete a payment. Instead of requiring the user to fill out a complex checkout form, the Payment Request API simplifies it down to a few taps, and can even integrate with other payment apps on the users device like PayPal or Android.
Another good example - media playback. With the media session API, you can provide metadata about what’s currently playing, and even handle media related events from the user. If the screen is locked, the user can quickly see what song is playing, and maybe skip to the next song.
Users don’t expect the web to work without a network connect, and often don’t even bother to try when it’s a slow or intermittent connection. We need to change that perception. Web apps must be reliable. When a user taps on a home screen icon, they expect it to load instantly and reliably. Launched from the home screen, it should never show the downasaur.
But what if you didn't need to traverse the network every time for every asset? What if you could intelligently cache assets locally, reliably?
That's what Service Workers do.
Service Workers enable you to implement caching with the Cache API, not just by hoping to rely on browser caching.
This means that after the first visit, sites and apps can be reliably fast.
An engaging app goes beyond functional, but ensures that the whole experience is delightful making it easy for the user to do what they need to do. Using features like Web Push, it’s always up to date, and Notifications keeps users informed. It uses the right capabilities, at the right time, in a beautiful way.
While mobile push notifications have existed for a while, I’m really excited we finally have access to them as web developers - even when your web application isn’t currently running, and the browser isn’t even open! On mobile devices, notifications are a fundamental part of turning a monthly active user into a daily active user; they truly unlock re-engagement, and a bunch of new use cases.
One of the things that has stuck with me is how their applications can stay in production for a really long time – as long as 5 or 10 years!
At the same time, the browsers considered “modern” today will be considered “legacy” tomorrow… so it’s unlikely they will be supported 5 years from now
There is a high cost associated with the long-term maintenance of enterprise applications, so I think it’s absolutely prudent to choose the webapplication stack very carefully.
Longevity
Enterprises need to think of creating web apps that last for 5-10 years. Creating maintainable apps is much easier when you have a single code base across multiple devices. You use latest Javascript standards, use full unit and functional testing.
Enterprises need to think about security, access control, compliance with privacy rules, along with containment and isolation of business data from personal data when the data is available for offline use. Also, enterprises need to deal with the management and provisioning aspects of deployment.
Additional security can be enforced by implementing Content Security Policies to identify legitimate sources of assets (images, etc.), and protect PWAs from attacks.
To remotely manage data sitting on a user's device, the cache can be named and a remote wipe method (invoked by the service worker) can be created.
A background synchronization can be implemented as a one-off or a periodic sync to ensure data integrity.
Developers have been using progressive development methodologies for years. It enables them to provide the best experience on fully-capable browsers and an acceptable experience on less-capable browsers. By detecting browser features, developers can drive specific application behaviors, even for enterprise applications. And to ensure that the UI fits for different form factors, developers can use media queries, layouts, viewport, and other responsive design building blocks. For many such capabilitues, there is really no new technology required specifically for PWAs.
For long running applications, it is important to be “functional” – by providing rapid iterative capability, optimization within apps and making apps performant. It is best to use key software plarforms to accomplish that
Most web applications have a set of common challenges.
The first challenge is how are you going to create the user interface elements - the widgets and charts and grids and the look of the application
The second challenge is how are you going to manage the layout and interactivity of your screen elements, and how are you going to do things like display your data in a high-contrast theme for accessibility, or adapt it for right-to-left languages like Arabic? And the newest problem: how are you going to build applications that work on both desktop screens with mouse input and mobile screens with gesture interactions.
The third challenge is how are you going to manage your local data. How are you going to update the screen when the data changes, and update your data when the user gives you input.
And finally, there’s the challenge of managing server communications.
But before we go into how you choose the best framework for your apps and your organization. It’s important to flesh out the basic geography of the most popular frameworks and libraries, because without a map it’s easy to get lost.
Lightning bolt - Functionality gap is mind boggling
HTML5 but CSS3 even more so require fundamental changes
Within our 8000 worldwide enterprise customers, applications developers are using Sencha to build business critical applications that drive global commerce and the world’s governments.
A Service Worker is a client-side proxy that you write in JS; after the first visit, the SW is installed and can respond to network requests. The SW can cache the resources you need for the page; this bit of proxy code is then loaded up whenever the subdomain is requested. The SW enables a developer managed cache that frees you to decide when to use the cache and when to hit up the network.
One of the cool things is that Service Workers can do more than just service network requests, they can service other system-level notifications - [CLICK] like push messages sent from an end point. The push notification is just another request that the SW services - it’s just a request from the outside, not from the web browser. It wakes up the SW, calls its onpush handler, and it’s done.
I'll say it again, because I think it's important, a Service Worker doesn’t consume any system processing resources until it’s woken up to handle an event. In fact, even if the browser is closed, the OS can wake up a service worker. We're no longer limited to the model where an “app must be loaded in an active tab” to be useful. This is important because it introduces an app-like lifecycle for the web.
When a service worker is first registered, it fires an "install" event which you can then use to pre-fetch and cache the resources your app needs. In effect, you’re running a fully scriptable install, much like a native app; but there are no bulky zip files and you have file-level control over what is fetched, how its cached and how it is updated.
Once the service worker has been activated, you now have full control over how the system services your app’s resources. You can inspect network requests, rewrite them, get a response from the network, respond with one of the resources you pre-fetched and cached when the service worker was installed. You can even synthesize your own responses.
All of this is completely transparent to the user - in fact, a well-constructed Service Worker can function as just a very smart caching system; a progressive enhancement of the network and cache, choosing smarter ways to respond to requests. It gives you the ability to make your apps reliable, even when the network isn't because you have full control over the response.
On the topic of “Service Worker as a progressive enhancement”, it’s important to understand that the FIRST time you load the page, it’s still going to be loading from the network - the index page has already been retrieved from the network, of course, and the page’s resources will kick off downloading normally. The Service Worker will come into play on subsequent loads, not the first load. Though, there is one caveat to that, I'll cover that in a moment.
Let’s walk through an example.
When this page is first loaded, it registers a service worker for a specific scope, we'll get into scopes in a few minutes, but for now, think of it as the set of pages the service worker will handle.
[CLICK] An install event is fired, and the code in your install handler is executed. [CLICK] Then, the service worker goes to idle, essentially sitting there quietly.
When the page is reloaded, or you hit another page covered by the service worker, the service worker becomes activated, ready to handle all of its events.
At the same time, [CLICK] the browser also makes an asynchronous request to the server to see if the service worker has changed since it was last retrieved.
Once the service worker has handled all of the events, [CLICK] it goes to idle, and eventually it's terminated, ready to spin up again when any new events come in.
Let's keep going with our previous example and see how a service worker gets updated. Since we've already been to the page, the service worker is already installed and is immediately activated. [CLICK] Then, just like before, the browser checks with the server to see if the service worker has changed, and this time, it has.
The new service worker is downloaded and installed - but it goes to idle and the original service worker is still activated. Our original service worker is still handling requests. In fact, our original service worker will remain active and serving requests until all of the clients using it have been closed.
This is an important point to remember as you're working on your own service workers. You may find yourself in situations where you have multiple service workers installed and waiting, because the original one, hasn't been terminated yet. There are ways to work around this but we’ll cover those a bit later.
The cache first with network fallback strategy we’ve laid out is pretty straightforward - always go to the cache first. If the request matches a cache entry, respond with that. Otherwise try to fetch the resource from the network. This option is good for resources that don't change, or have some other update mechanism. It will give you a very fast response - since objects come out of the cache directly - but it doesn’t update. On the negative side, if an item isn't in the cache, it's not automatically added after its retrieved from the network.
The network, falling back to cache strategy means you give online users the most up-to-date content, but offline users get an older cached version. If the network request succeeds you'll most-likely want to update the cache entry. However, this method has flaws. If the user has an intermittent or slow connection they'll have to wait for the network to fail before they get the perfectly acceptable content already on their device. This can take an extremely long time and is a frustrating user experience.
Cache, then network requires the page to make two requests, one to the cache, one to the network. The idea is to show the cached data first, then update the page when/if the network data arrives.
You could also do a generic fallback solution where a request is made first to the cache, then the network, and if both of them fail, a second request is made to the cache for a generic page.