Angular Service Workers - aakash14goplani/FullStack GitHub Wiki

Topics Covered

Introduction

  • JavaScript code runs in a single thread. All the pages in our web application utilizes that single thread.

  • JavaScript offers us to run an additional thread called Service Worker. Important part is that this thread is kind of decoupled from your HTML pages. This can also continue running in the background and perform advanced things like receive push notifications etc.

service workers

  • Service Worker can listen to outgoing network request and it can cache some objects in browsers cache storage and return these cached responses back to your page so that it also works if you've got no internet connection.

Adding Service Workers

  • Run ng add @angular/pwa to add PWA library and this will actually configure your existing project to use the angular service worker package and start with a pre-configured service worker.

  • This package adds couple of new configuration files and also modifies existing HTML and Typescript code to refer these new files

  • Service Worker can only kick start when you're building for production. When you run command ng build --prod in the generated dist folder you can see multiple files and icons added by this package so that you Angular app can work in offline mode as well.

  • Once your app is build for production you need a server to host that, we will use http-server.

    • in cmd cd to dist folder
    • npx http-server -p 4201
  • In Google Chrome > Applications Tab > Service Worker > check offline mode - this simulates offline mode. Now you can see you got a blank white page, although no content is shown but you don't see regular "No Internet Connection" page. This proves your service worker is configured correctly and is up and running.


Caching Assets for Offline Use

  • We have to configure ngsw-config.json file to add assets that needs to be cached for offline use. Structure of this file is:
    • index - indicates the root page of our app we want to cache
    • assetGroup - It's an array and in there we got groups that are configurations that define which static assets should be cached and how they should be cached dynamic assets for example would be the data from the API.
    • name - We can give such a group a name whichever name you like
    • installMode - you can then define how should these assets be loaded prefetch means that when your page loads angular will go ahead or the service worker will go ahead and already prefetch all the assets which are specified in this asset group. Other option is lazy which assets that requires to be loaded just once. The advantage of lazy is that you don't occupy all the bandwidth right at the beginning. The downside is that if you need it for the first time it will not be there. So if the user loses the internet connection before the asset let's say to see is as Fall is required the first time it will not work because it will not be cached with prefetch it will be cached even before you need it there also is update mode.
    • resources - the assets which should be loaded are specified here. It has one key property the files and there you have an array pointing to the files you want to cache. These files will always seen relative from the dist folder.
"$schema": "../../node_modules/@angular/service-worker/config/schema.json",
  "index": "/index.html",
  "assetGroups": [
    {
      "name": "app",
      "installMode": "prefetch",
      "resources": {
        "files": [
          "/favicon.ico",
          "/index.html",
          "/manifest.webmanifest",
          "/*.css",
          "/*.js"
        ],
        "urls": [
          "https://fonts.googleapis.com/css?family=Oswald:300,700",
          "https://fonts.gstatic.com/**"
        ]
      }
    }, 
  • So we use assetGropus to cache all Static data

Caching Dynamic Assets and URLs

  • We add a new configuration item and that would be dataGroups to add dynamic data that needs to be cached.

  • dataGroups - is an array wherein you have a key url where you can specify the PSOT URLs that you application makes.

  • You can also specify cache strategy and configurations like maximum size, age and timeout

    • maxSize - defines how many entries do you want to cache in. Example if your post request return 1000 entries and you just want to cache top 10, you can specify 10 here.
    • maxAge - specifies how old should the data in the cache be before we get rid of it and fetch new data.
    • timeout - Use cache after specified amount of time. Example: you could say if I'm waiting for a response for let's say 10 seconds already then I want to fall back to the cache and not wait longer but I don't want to use to cache immediately.
    • strategy - They're can have two types, first is, freshness which means always try to reach out to the backend first and only use the cache if you're offline. Second is performance t that ties to get something onto the screen as quick as possible and it will take max age into account to know whether it should absolutely reach out to the backend or just use the cache value.
 "dataGroups": [
    {
      "name": "posts",
      "urls": [
        "https://jsonplaceholder.typicode.com/posts"
      ],
      "cacheConfig": {
        "maxSize": 5,
        "maxAge": "6h",
        "timeout": "10s",
        "strategy": "freshness"
      }
    }
  ]
  • Note: Now when you tap reload at least once so that the API responses can be cached the first reload loads the service worker. The second one loads the API responses then turn off the Wi-Fi or switch to offline simulation and load again and see response from service worker