title | order | layout |
---|---|---|
Progressive Web Application |
800 |
page |
Progressive Web Apps (PWAs) are regular web pages that can look like traditional desktop applications, or like modern native mobile Apps by combining modern browsers features.
The main keys for a web application to be considered a PWA are:
-
Progressive: should not have technological or accessibility restrictions.
-
Responsive: screens need to adapt to any device, and still be fully usable.
-
Network independent: able to start without network, and aware of network failures
-
App like: look like a native application
-
Fresh: updates happen transparently to the user
-
Safe: secure connections
-
Discoverable: user knows the App by visiting a page
-
Re-engageable: background notifications invite users to come back to the application
-
Installable: can be installed in the device home-screen, and opened like other native apps
-
Linkable: users can send links to the application
Bakery fulfills most of the requirements for a Progressive Web App:
-
Its UI is responsive, accessible, and looks like a native application, it gets updates from server on new versions, and all the stages of the application have a linkable URL.
-
Flow server automatically serves resources needed for PWA, such as
manifest
file that makes the App discoverable and installable, as well as a service worker that facilitates certain parts of the App to be cached for offline. -
Bakery can be started when the device is offline, noticing to the user about the issue, and loading the UI when it is online.
-
It prevents the user to interact with the UI when the network is down.
Flow provides an easy way to configure a PWA application. In case of Bakery it is only needed to annotate the AppShell
class with a @PWA
, provide an offline-page.html
and few info about the application:
@PWA(name = "Bakery App Starter", shortName = "###Bakery###",
startPath = "login",
backgroundColor = "#227aef", themeColor = "#227aef",
offlinePath = "offline-page.html",
offlineResources = {"images/offline-login-banner.jpg"})
Note that there should be allowed access to the resources: manifest.webmanifest
, sw.js
, offline-page.html
, as long as to the images and icons. This is done in SecurityConfiguration
class:
@EnableWebSecurity
@Configuration
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
@Override
public void configure(WebSecurity web) throws Exception {
web.ignoring().antMatchers(
...
"/manifest.webmanifest",
"/sw.js",
"/offline-page.html",
...
);
}
}
We use Vaadin routing annotations so as each stage of the application has a unique URL that can be linkable.
As we already know manifest
file is served and generated by Flow according to the provided @PWA
configuration. There we can customize how the icon looks in the home-screen and task manager, as well as the splash-screen and background.
The presence of a manifest.webmanifest
and a Service-Worker, allows that the user will be prompted to install the App when visiting the web site a few times.
Tip
|
Chrome criteria for displaying the install banner is to register a service worker, to serve the page over HTTPS , and to provide name , short_name , start_url and 192x192 icon in manifest.webmanifest .
|
Once you have the app-icon installed on your home-screen, click on it. Bakery will open in full-screen like a native app, you can see a splash-screen when it is opening.
In the following image, you can compare the App running in a tablet when it is opened from the home screen - looking as native, or in the browser - looking as a standard web page.
Bakery utilizes a bunch of techniques to look as a native application, and to adjust to the device screen size.
-
A responsive Web components selection:
-
vaadin-grid
for displaying data without consuming so much resources. -
vaadin-dialog
is used for displaying forms, this guarantees that we can control whether the form is shown as a modal layer, or in full screen. -
vaadin-form
to configure responsive steps based on the viewport. -
vaadin-tabs
is able to adapt to the available space an show navigation arrows in case. -
vaadin-board
a responsive component used in the dashboard.
-
-
Vaadin themes for small visual variants in the components.
-
CSS media queryes for fine control, and to set CSS properties based on screen size.
Note
|
in Bakery, custom styling of a specific template is done in its file, but component theming and common for the App styles are gathered in the shared-style.css file.
|
By using vaadin-core-elements
it is guaranteed that screens are accessible
-
vaadin-text-field
andvaadin-password-field
for accessible text inputs. -
vaadin-dialog
deals with trapping the focus in the overlay and much more. -
vaadin-date-picker
andvaadin-combo-box
are specialized form-components accessible for everyone. -
vaadin-tabs
allows navigate and announce pages with keyboard or mouse. -
vaadin-grid
makes easy to navigate cells with the keyboard.
The way to make an application available when offline, is by providing a Service Worker.
The sw.js
script is generated by Flow according to @PWA
configration and it has all the magic for determining what should be cached, and what should be done in case of a network failure. Example of generated sw.js
:
importScripts('/bakery/VAADIN/static/server/workbox/workbox-sw.js');
workbox.setConfig({
modulePathPrefix: '/bakery/VAADIN/static/server/workbox/'
});
workbox.precaching.precacheAndRoute([
{ url: 'icons/icon-144x144.png', revision: '-1619375005' },
{ url: 'icons/icon-192x192.png', revision: '429260614' },
{ url: 'icons/icon-512x512.png', revision: '-381362175' },
{ url: 'icons/icon-16x16.png', revision: '1640292953' },
{ url: 'offline-page.html', revision: '-2067995194' },
{ url: 'manifest.webmanifest', revision: '-37768073' },
{ url: 'images/offline-login-banner.jpg', revision: '1610653180' }
]);
self.addEventListener('fetch', function(event) {
var request = event.request;
if (request.mode === 'navigate') {
event.respondWith(
fetch(request)
.catch(function() {
return caches.match('offline-page.html');
})
);
}
});
Due to the nature of Vaadin, the UI is managed from server side, thus the application will be unusable when the server is unavailable.
In Bakery, we provide a mechanism to notice the user about the offline issue when it happens. It shows an advice that covers the screen and prevents user interaction. The notice will disappear as soon as the network becomes available.
This is performed in the main-view.js
template. The significant blocks here is the html defining the message to show, and the code detecting network changes.
...
<div class="offline" hidden$="[[online]]">
...
</div>
...
<script>
class MainView extends Polymer.Element {
...
ready() {
super.ready();
this.online = window.navigator.onLine;
window.addEventListener('online', () => this.online = true);
window.addEventListener('offline', () => this.online = false);
}
...
}
<script>
In the following screenshot, you can view how the message is displayed in Bakery when you check or uncheck the offline box in browser devtools.
Here are some further topics you might want to review: