What Are Progressive Web Apps (PWA) And How To Implement PWA Using Angular

Progressive Web Apps are like websites…but better. It is a new way to deliver amazing mobile application capabilities using websites. PWA was introduced by Google in Google I/O 2016, and since then it has become  the talk of the town. Progressive Web Apps are applications that use modern web capabilities to provide a mobile application-like experience to users via the web. It's still a relatively new concept to talk about, with many pros and cons...


Progressive Web Apps are

  • Reliable
    Service Workers enable PWA to load instantly, regardless of the network state. It never shows that awful dinosaur screen, even if there is no network.

  • Fast
    Application Shell makes it faster and provides a smooth user experience.

  • Engaging
    Manifest makes more engaging web apps. Manifest file makes PWA installable and live on the user’s home screen. We can even make the users re-engaged with the help of push notifications.

  • Progressive
    Works for every user, regardless of browser.

  • Safe
    PWA Served via HTTPS to prevent snooping and ensure the security of content.

  • Linkable
    It can be easily shared via URL.

Source Code and Demo Application

Implement PWA using Angular

Ahead-of-Time(AOT) compilation

One way to make an Angular app load faster is to run its compiler under the AOT. i.e. the compiler only runs once during the build step only; the app does not need to compile when trying to load it in browser.

With Angular-cli, it is as simple as writing one command line statement.

ng build - -prod - -aot

And that’s it. Now, just run and check it, which will make your application 50% faster and also reduce the bundle size to 45% . Isn’t it awesome guys!!!

Service Worker

It is an entirely separate script file that runs in the background of your browser. We first need to register service worker before using it. We can do that by simply putting the below script into html.
  1. [code language=”html”]  
  2. <!doctype html>  
  3. <html>  
  5. <head>  
  6.   <meta charset="utf-8">  
  7.   <title>Pwa1</title>  
  8.   <base href="/">  
  10.   <meta name="viewport" content="width=device-width, initial-scale=1">  
  11.   <link rel="icon" type="image/x-icon" href="favicon.ico">  
  12.   <link rel="manifest" href="/manifest.json">  
  13.   <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u"  
  14.     crossorigin="anonymous">  
  16.   <!-- Optional theme -->  
  17.   <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap-theme.min.css" integrity="sha384-rHyoN1iRsVXV4nD0JutlnGaslCJuC7uwjduW9SVrLvRYooPp2bWYgmgJQIXwl/Sp"  
  18.     crossorigin="anonymous">  
  20. </head>  
  22. <body>  
  23.   <app-root>Loading...</app-root>  
  24.   <noscript>  
  26.     <h4 style="font-family: 'HelveticaNeue-Light', 'Helvetica Neue Light', 'Helvetica Neue', Helvetica;">  
  27.       Sorry, JavaScript needs to be enabled in order to run this application.  
  28.     </h4>  
  29.   </noscript>  
  31.   <script>  
  32.     if ('serviceWorker' in navigator) {  
  33.       navigator.serviceWorker.register('/service-worker.js').then(function (registration) {  
  34.         // Registration was successful  
  35.         console.log('ServiceWorker registration successful with scope: ', registration.scope);  
  36.       }).catch(function (err) {  
  37.         // registration failed :(  
  38.         console.log('ServiceWorker registration failed: ', err);  
  39.       });  
  40.     }  
  41.   </script>  
  42. </body>  
  44. </html>  
  46. [/code]  

This script will check if the browser supports Service Worker or not. If it supports service worker, it will register it. Now, we require service worker precache which will generate service worker module.

We can add sw-precache by simply writing

 npm install - - save-dev sw-precache

Now, in your package.json file, add precache script.

  1. [code language=”javascript”]  
  2. {  
  3.   "name""pwa1",  
  4.   "version""0.0.0",  
  5.   "license""MIT",  
  6.   "scripts": {  
  7.     "ng""ng",  
  8.     "start""ng serve",  
  9.     "build""ng build",  
  10.     "test""ng test",  
  11.     "lint""ng lint",  
  12.     "e2e""ng e2e",  
  13.     "precache""sw-precache --verbose --config=sw-precache-config.js"      
  14.   }  
  16. [/code]  

And also, add the following file to root directory of you Angular project and name it as sw-precache-config.js, which contains information about what files are to be cached.

  1. [code language=”javascript”]  
  3. module.exports = {  
  4.   staticFileGlobs: [  
  5.     'dist/**.html',  
  6.     'dist/**.js',  
  7.     'dist/**.css',  
  8.     'dist/images/*',  
  9.     'dist/icons/*'  
  10.   ],  
  11.  root: 'dist',  
  12.   stripPrefix: 'dist/',  
  13.   navigateFallback: '/index.html',  
  14.   runtimeCaching: [{  
  15.     urlPattern: /rkdemotask\.herokuapp\.com/,     
  16.     handler: 'networkFirst'  
  17.   }]  
  18. };  
  21. [/code]  

Here, I am caching all HTML, CSS, and JS files to dist folder because when we run the production build with Angular cli, it generates the compiled and minified bundle in dist directory which we deploy and host on Server.

All done now. If we want to enable service worker, we need to follow the following steps.

  1. ng build - - prod - - aot
  2. npm run precache

Here, the second step will generate serviceworker.js file in our dist directory.


On first time load.


On repeated visit

App Manifest

We can give users "add to home screen" prompt in order to provide them mobile application feel. To do so, we only need to add JSON file inside our src directory. Before that, we need to do some adjustment in index.html as shown below.

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

And one more change in our .angular-cli.json file is needed. 

  1. "assets": [  
  2.          "assets",  
  3.          "favicon.ico",  
  4.          "manifest.json"  
  5.          ],  

Finally, the manifest.json file

  1. [code language=”javascript”]  
  3. {  
  4.   "name""jinal shah",  
  5.   "short_name""jinal shah",  
  6.   "icons": [  
  7.     {  
  8.       "src""assets/icons/logo.png",  
  9.       "sizes""192x192",  
  10.       "type""image\/png"  
  11.     }  
  12.   ],  
  13.   "display""standalone",  
  14.   "start_url""./?utm_source=web_app_manifest"  
  15. }  
  17. [/code]   

We can even add splash screen in the manifest file.



Hope this article will be helpful to you.

Source courtesy