Chapter 13.Progressive Web Apps

Since Ionic apps are built with web technologies,you might be wondering if they can be deployed as a traditional web app viewable via a standard browser. The simple answer is yes. That is what we have been doing while we were building and testing our application with$ ionic serve. You can certainly take the contents of the_www_directory and place them on your web server.The main caveat is that none of the Cordova plug-ins will function in this environment. The best way to think about publishing your application this way is to think of it as a completely new platform: the browser.

While we don’t have the same capabilities that a native application might have, today’s modern browsers do support several key features, such as geolocation, notifications, and offline storage.

One of the challenges in delivering your application in this manner is the overall file size of our Ionic application.The_main.js_file that is generated by the CLI (using$ ionic cordova build --prod), starts just under 2 MB.

REDUCING FUTURE BUILD SIZES

The Ionic team is actively working with Angular to reduce the file size of the application further.

Then start factoring in all your visual assets and any other resources you might need very quickly, your app will probably run very slowly as all these items are each fetched across the network. Compound this if you are running over a cellular network or a weak WiFi connection.

However, there is a new idea that is gaining a lot of traction within the web app development community:progressive web apps. Originally proposed by Google in 2015, this solution takes advantage of the latest technologies to combine the best of web and mobile apps. While not every browser supports all the features of a complete progressive web app, there is enough support to consider it as an option.

But What, Exactly, Is a Progressive Web App?

According toGoogle Developers, a progressive web app uses modern web capabilities to deliver an app-like user experience.

Let’s start with the first term in the name: progressive. By definition, a progressive web app must work on any device and have its functions enhanced in a progressive manner. That is, if the device is more capable, then the app can use that capability. If a feature is not supported, then the web app offers an alternative experience.

Progressive Web Apps are also both discoverable and linkable, meaning that both users and search engines can discover the content within the app. This lack of discoverability is one clear disadvantage of native apps. Since our app exists within the web, users should be able to link or bookmark their “place” within the application and return to it.

Since we are expanding beyond the confines of fixed screen sizes, these applications must also be responsive in their visual design. In reality, although screen sizes are fixed on mobile devices, the range of device screen size causes us to already have addressed this issue.

In terms of visual design, a progressive web app should look and feel like a native application. Again, this is an example of leveraging Ionic’s components to achieve this with little effort.

We also need to break free from the browser itself and become something that the user can install on their device’s home screen. Otherwise, it becomes too burdensome for users to use your application if they have to launch the browser, navigate to a URL or recall it from a bookmark.

The interactions are also considered “safe”—for a progressive web app to function, it must be served over an HTTPS connection.

Finally, it must work without a network connection. Again, once a native app is installed, it is available for use. Progressive web apps must offer the same level of functionality.

Now that you have a sense of the requirements for a progressive web app, let’s look at what we need to do to make our Ionic application into a progressive web app.

The manifest.json File

If you recall when we were exploring the files and directories of our Ionic application, there were two files that we skipped over: the_manifest.json_and_service-worker.js_files.

First, let’s make our web app more app-like in appearance. To do this, we can leverage the_manifest.json_file. This file follows theW3C specification for web apps. Here is the default_manifest.json_file that is auto-generated for us:

{
  "name": "Ionic",
  "short_name": "Ionic",
  "start_url": "index.html",
  "display": "standalone",
  "icons": [{
    "src": "assets/imgs/logo.png",
    "sizes": "512x512",
    "type": "image/png"
  }],
  "background_color": "#4e8ef7",
  "theme_color": "#4e8ef7"
}

Let’s look at thesepropertiesin more detail:

name

This is the name that will be used for the application listing.

short-name

This is the name that is usually displayed along with the home screen icon.

start_url

The entry point to your applications, usually it is your index.html file.

display

Defines how the browser should display the web application. The options are: fullscreen, standalone, minimal-ui, or browser. Here is what each option does:

fullscreen

The web application is shown without any browser chrome and will take up the entire display area.

standalone

The web application will be launched to look and feel more like a standalone native application. The browser chrome will not be displayed but, can include other system UI elements such as a status bar and/or system back button.

minimal-ui

The web application will be shown with a minimal set of UI elements for controlling navigation (i.e., back, forward, reload, and perhaps some way of viewing the document’s web address).

browser

The web application will be shown in the standard browser chrome.

icons

This array defines the various icons that will be used by the home screen, task switcher, and so on. It is an array of objects defines the icon url, size and file type. We recommend having 48, 96, 144, 192, and 256-pixel icons specified.

background_color

This hex value defines the background color of the web application. In Chrome, this value also defines the background color of the splash screen.

theme_color

On Android, this hex value is used define the color the status bar.

Not listed in the auto-generated version of the_manifest.json_file is theorientationproperty. This property will define the default orientation for the application. It can be either portrait or landscape.

This file is already referenced within our_index.html_in the head tag:

<
link rel="manifest" href="manifest.json"
>

Service Workers

The engine of every progressive web app is actually the Service Worker API. This API introduces another layer between the code that runs within your application and the code that might run on a remote server. This code acts an intermediary between our client and server. Once the service worker is registered, it sits independently of any browser window or tab.

This API is currently supported in Chrome, Firefox, and Opera, and it is coming very soon to Edge. Apple’s WebKit team has it marked “under consideration.”

Service workers have the ability to intercept and rewrite all of your application’s network requests. This gives you the ability to provide cached responses when there is no data connection available. Because of this ability, it will only function in secure contexts (i.e., HTTPS).

Within the default_index.html_file, the Ionic team has included a snippet of code to assist in registering your app’s service worker. By default, this code is commented out:

<
!-- un-comment this code to enable service worker

<
script
>

  if ('serviceWorker' in navigator) {
    navigator.serviceWorker.register('service-worker.js')
      .then(() =
>
 console.log('service worker installed'))
      .catch(err =
>
 console.log('Error', err));
  }

<
/script
>
--
>

This snippet will simply register it if it is supported by the browser.The real code is within the_service-worker.js_file.

The auto-generated_service-worker.js_is nicely commented, and we won’t rehash it here. Instead, let’s look at this basic service worker sample, so you can understand what you can do with a service worker.

Let’s replace the default_service-worker.js_with this. But, before you do, go ahead and save a copy of the original_service-worker.js_file. Here is the new code:

self.addEventListener('fetch', function(event) {
  if (event.request.url.indexOf('/img/my-logo.png') !== -1) {
    event.respondWith(
      fetch('/img/my-logo-flipped.png')
    );
  }
});

This sample will intercept any request for/img/logo.pngand instead return the flipped version.

Remember, in order for this to function, it must be served on an HTTPS connection and by a supported browser.

By properly caching our assets, we can reduce our applications’ start times dramatically. In fact, we should be able to launch faster than a native application!

Note that because a service worker is a special type of shared web worker, it runs in a separate thread to your main page’s JavaScript. This means that it is shared by all web pages on the same path as the service worker. For example, a service worker located at/my-app/sw.js_would be able to affect/my-app/index.htmland_my-app/images/header.jpg, but not/index.html.

Beyond intercepting our network requests, it can provide offline functionality, push notifications, background content updating, content caching, and a whole lot more.

Here is a sample of providing a custom text response if you are offline when trying to access the web app:

self.addEventListener('fetch', function(event) {  
  event.respondWith(
    fetch(event.request).catch(function() { 
      return new Response(
        'Welcome to the Upside Down.\n'+
        'Please look out for the Demogorgon.\n'+
        'We look forward to telling you about Hawkins National Laboratory 
         as soon as you go online.'
      );
    })
  );
});

Reload your browser with this service worker installed, then reload your page, but this time offline. Instead of the default not-connected screen, we will be presented with this information instead. With a little work, you could provide a custom experience, including images and stylesheets.

Here is a sample of caching most of the default Ionic files and returning the cached version if the user is offline:

var CACHE_NAME = 'ionic-cache'; 
var CACHED_URLS = [
  '/assets/fonts/ionicons.eot',
  '/assets/fonts/ionicons.scss',
  '/assets/fonts/ionicons.svg',
  '/assets/fonts/ionicons.ttf',
  '/assets/fonts/ionicons.woff',
  '/assets/fonts/ionicons.woff2',
  '/build/main.css',
  '/build/main.js',
  '/build/polyfills.js',
  'index.html'
];

self.addEventListener('install', function(event) { 
  event.waitUntil(
    caches.open(CACHE_NAME).then(function(cache) { 
      return cache.addAll(CACHED_URLS);
    })
  );
});

self.addEventListener('fetch', function(event) { 
  event.respondWith(
    fetch(event.request).catch(function() {
      return caches.match(event.request).then(function(response) {
        return response;
      });
    })
  );
});

Service workers have tremendous potential to improve the user experience of our applications. Besides providing a solution for our application to function in an offline mode, they can also be used when the user might have a poor network connection. Consider how much of your application might be very static in nature and could always be served locally, rather than making a network request.

Push Notifications

Another new API that bridges the gap between native mobile applications and the web is the Push Notification API. This API also leverages the use of service workers in order to receive the notification when no browser is open. For more information about adding push notifications to your progressive web app, check out sometutorials from Google.

What’s Next?

Progressive web app support will continue to grow with the Ionic Framework, so look for additional enhancements to be added over time. Ionic has a collection ofprogressive web app samples.

NOTE

Ionic has indicated that they will be migrating fromService Worker ToolboxtoWorkboxfor their service worker library. If you are planning to deploy your Ionic application as a PWA, you will want to check the status of this migration via the Ionic blog.

To learn more about progressive web apps in general, we suggest getting a copy ofBuilding Progressive Web Apps: Bringing the Power of Native to the Browser, by Tal Ater (O’Reilly).

results matching ""

    No results matching ""