Slide 1

Slide 1 text

Let’s Keep in Touch: Building a Website that works without Internet Using Angular, Service Workers and Firebase Tomiwa Ademidun 1

Slide 2

Slide 2 text

What Are We Going To Build ● A Progressive Web App that works without the internet (offline-first) ● The Website: demo.atila.ca ● Theory on how service workers work ● Application: Live Practical Tutorial on how to build offline-first web apps ● Bonus: Rant on Why this is awesome 2

Slide 3

Slide 3 text

Different Formats of this Talk This tutorial is available as a... 1. Slideshow 2. Video 3. Blog 4. Podcast 5. Source Code 3

Slide 4

Slide 4 text

Theory What’s an offline first-web app??? What’s a service worker??? Why should I care??? Is there free food after this??? 4

Slide 5

Slide 5 text

About Me ● Tomiwa Ademidun, software engineering and business student at Ivey Business school, Canada ● Founder atila.ca, easily find and apply to scholarships. ● Founder of software engineering studio, tech.atila.ca ● Software Engineering Intern @ Properly, Employee #2 ● My Website: tomiwa.ca ● Follow me on Twitter: @tomiwa1a 5

Slide 6

Slide 6 text

What does this diagram represent? 6

Slide 7

Slide 7 text

Alibaba, Amazon, Instagram etc. are very powerful websites, but have one flaw ● Alibaba $25 billion in sales in one day (singles day) ● 40% of cloud computing clients Amazon Web Services Including: Apple, Netflix and CIA ● 2.2 Billion people use Facebook every month, 700 million Instagram ● But without wifi, the entire site is unusable 7

Slide 8

Slide 8 text

No Internet, No Fun With internet Without internet 8

Slide 9

Slide 9 text

Atila is not quite as large, but its always there for you ● Humble, little atila.ca has much fewer users ● But with or without internet you can still use atila.ca ● Google Drive also does this really well 9

Slide 10

Slide 10 text

No Internet, No Problem With internet Without internet 10

Slide 11

Slide 11 text

No Internet, No Problem With internet Without internet: metaphorically “Raise your hand” if you knew you could use Google Drive without internet? 11

Slide 12

Slide 12 text

What does this diagram represent? Millions of Daily Users Works Offline 12

Slide 13

Slide 13 text

What is a Service Worker? ● A proxy/messenger between your browser and the internet ● When your web app asks for resources (images, html files, json API etc.) the service worker gets it for you without asking internet ● In literal terms, it is a javascript file that gets shipped along with the rest of your app 13

Slide 14

Slide 14 text

● The service worker intercepts each request your browser makes and tries to fulfill the request itself ● First it checks its local cache to see if it has the resources you need ● If it doesn’t: a. Goes to the network and asks for the resources b. Saves resources to its local cache c. Serves you the resources from its cache ● Works both with and without internet a. Faster connections even with internet How Does It Work? 14

Slide 15

Slide 15 text

Enough Talking, Let’s Build it! 15

Slide 16

Slide 16 text

Prerequisites ● Node.js® and npm ○ Make sure you have node 8.X or greater (node -v ) and npm 5.x or greater ( npm -v) ● Globally install Angular CLI ○ npm install -g @angular/cli ● Google Chrome Browser (optional, but recommended) ● Google Account (optional if you want to deploy to Firebase) 16

Slide 17

Slide 17 text

Clone the atila web app ● Go to https://github.com/atilatech/atila-web-app ● Clone the demo.atila.ca web app from Github: atila-web-app ○ Checkout the pwa-tutorial branch: git checkout pwa-tutorial ○ Checkout the tutorial start commit: git checkout pwa-tutorial-0.0 ○ Install npm modules: npm install ○ Start the app!” ng serve -o ○ If you get an No NgModule error. Go to any .ts file and put a space ■ Very weird bug! Learn More 17

Slide 18

Slide 18 text

Install the Service Worker Module 1. Install the @angular/serviceworker module: a. npm install @angular/[email protected] --save 2. Tell angular-cli to build project with service worker: a. ng set apps.0.serviceWorker=true 3. Configure your service worker in ngsw-config.json 4. Add a manifest.json file and reference it in index.html Further Reading: ● Transforming an existing Angular application into a Progressive Web App ● Turning an Angular 6 app into a Progressive Web App 18

Slide 19

Slide 19 text

Not Just Copy Paste, What does it Mean Starting Git Tag: pwa-tutorial-0.0 19

Slide 20

Slide 20 text

Install the Service Worker Module: #3e66c3a ● npm install @angular/[email protected] --save: ○ This module contains the service worker objects that we will be using in the next step ● Ng set apps[0].serviceWorker=true: ○ Tell angular CLI to automatically produce a javascript file that contains the code for the service worker, when building project explained in next step 20

Slide 21

Slide 21 text

Service Worker Configuration ● This tells your service worker, exactly what files it should be saving and how it should be saving them: ● assetGroups: files that are included as part of the app, ○ When the app updates, these resources update as well ● dataGroups: external resources not versioned with app ● Install Mode: What caching strategy to use when first seeing this file ● UpdateMode: What caching strategy to use when updating the file, after we’ve already installed it ● Caching strategy: ○ Prefetch: Save these files before we even ask for it ○ Lazy: Save these files only after they’ve been requested at least once 21 Further Reading: ● https://angular.io/guide/service-worker-config Github Gist / Github Diff

Slide 22

Slide 22 text

Manifest.json ● This is what turns your app from a web app to a progressive web app ○ Basically a web app that behaves like a native mobile app ● Allows users to install your app to home screen ● Add the home screen icon ● Reference it in index.html 22 { "name": "Atila", "short_name": "Atila", "start_url": "index.html", "display": "standalone", "icons": [{ "src": "assets/img/favicon-bg.png", "sizes": "512x512", "type": "image/png" }], "background_color": "#194f87", "theme_color": "#194f87" } Further Reading: ● Google Web Fundamentals: Add to Home Screen ● Google Web Fundamentals: Web App Manifest

Slide 23

Slide 23 text

Register the Service Worker: #d2b186f ● Tell app our service worker exists ● Add the service worker module to app.module.ts ● Register the service worker in main.ts ○ Check if the browser has service worker support // src/main.ts if ('serviceWorker' in navigator && environment.production) { console.log("Service Worker in main.ts"); window.addEventListener('load', () => { console.log("on page Load Service Worker in main.ts"); navigator.serviceWorker.register('/ngsw-worker.js', { scope: '/', }) .then(registration => { console.log("Service Worker registration completed main.ts", registration); }); }); 23 // src/app.module.ts import {ServiceWorkerModule} from '@angular/service-worker'; … Imports: [ …, ServiceWorkerModule.register('/ngsw-worker.js', {enabled: environment.production}),]

Slide 24

Slide 24 text

Part 1a: Build The Service Worker 24

Slide 25

Slide 25 text

The service Worker Output ● Build your app ○ ng build --prod ● Let’s look at the additional files that were produced in dist/ 1. Ngsw.json 2. ngsw-worker.js 25

Slide 26

Slide 26 text

The service Worker Output: ngsw.json ● This file was generated based on the instructions from the ngsw-config.json files ● It tells your serviceworker to cache any of the files in this list ● Caching strategy: ○ Prefetch: Save these files before we even ask for it ○ Lazy: Save these files only after they’ve been requested at least once 26

Slide 27

Slide 27 text

The service Worker Output: ngsw-worker.js ● This file is literally the service worker ● We registered it earlier in our main.ts file ● A plain javascript file containing the code and logic for how your service worker registers and caches your service worker to database ● If you’re up for a challenge, try looking through the code and see if you can understand what is happening ● Add Screenshot of ngsw.js 27

Slide 28

Slide 28 text

Part 1b: Testing The Service Worker Github Commit: #2001441 28

Slide 29

Slide 29 text

Creating A Mini Server ● Service workers are used in an offline contexts, so we need a server that can simulate offline environments ● Install npm http server ○ Npm install [email protected] --save-dev ● Build and Run the server ○ ng build --prod (optional) ○ http-server -p 8080 -c-1 dist 29

Slide 30

Slide 30 text

Inspecting the Server Requests ● Visit Chrome Network tab in devtools ○ Do this before going to localhost! ○ Open a new tab ○ Right click somewhere blank on screen ○ Inspect > go to Network Tab ● Open http://localhost:8080/ 30 ● Note that there is no wi-fi in top right ● See console: The external network resources fail with 504 but our files are succesful (200)

Slide 31

Slide 31 text

Where are the Files Being Saved? ● Open the application tab in Devtools and you will see local cache section ● This is the “database” where the service workers are saving your files ● That’s it! You now have a simple but fully functional offline first web app. Continue to part 2 for adding more cool features 31 Further Reading: ● Angular University: Angular Service Workers

Slide 32

Slide 32 text

Part 2: Saving External Data Part 1 Git Tag: pwa-tutorial-0.1 32

Slide 33

Slide 33 text

Why are None of My APIs Working? ● When you try to click on a link, you will notice a server error ● Your service worker doesn’t have those APIs in your database, but we can add it ● Pop Quiz! If we want to tell our service worker to cache a new type of file where should we put the code to do so: a. Manifest.json b. Ngsw-config.json c. app.module.ts 33

Slide 34

Slide 34 text

Saving External API calls: Configuration ● Now we will configure our ngsw-config.json to cache external API urls as well ● Two caching options a. Freshness: Go to the network first, if missing, go to the b. Performance: Go the cache first, then go to network 34 Github Diff Further Reading: ● https://angular.io/guide/service-worker-config

Slide 35

Slide 35 text

Saving External API calls: #8593ada ● You might need to use a seperate URL that allows your app to access it via CORS ● We will use a special JSON service to simulate (“mock”) our blog API ○ Since We don’t have permission to use official Atila API’s ● Change ScholarshipService.getPaginatedScholarships: ○ Go to src/app/_service/scholarship.service.ts#L47 ○ Change: this.http.post(`${this.scholarshipsPreviewUrl}?page=${page}/`, form_data) ○ To: this.http.get(`https://api.myjson.com/bins/dx1dc`) ● Change BlogPostService.getBySlug: ○ Go to src/app/_service/blog-post.service.ts#L25 ○ Change: this.http.get(`${this.blogUrl}blog/${username}/${slug}/`) ○ To: this.http.get(`https://api.myjson.com/bins/v5ow0`) 35

Slide 36

Slide 36 text

Part 3: Notify Users of New Updates Part 2 Git Tag: pwa-tutorial-0.2 36

Slide 37

Slide 37 text

Notifying of New Updates ● When a new version is available from network, service worker still serves the old version in cache to save time ● Add your profile to team page ○ src/app/team/team.component.ts ○ Add your image and some information in the team data array ● Rebuild project and restart server ● You’ll notice that your profile doesn’t appear yet 37

Slide 38

Slide 38 text

Notify Users of New Updates: Snackbar ● Rebuild project and restart server ● We can add a snackbar to notify user of new updates ○ npm install @angular/[email protected] --save (you might already have this) ● Then we create swUpdate to listen for updates from the SW and update if a new version is available.Github Diff ● Rebuild and reserve your application (see slide 24) 38

Slide 39

Slide 39 text

Part 4: Deployment Part 3 Git Tag: pwa-tutorial-0.3 39

Slide 40

Slide 40 text

Deploy to Firebase Hosting ● To truly see effect of service worker we should probably deploy it to a real website: Deployment Prerequisites: 1. Create a google account 2. A firebase account and a firebase project 3. install firebase tools globally: npm install -g [email protected] 4. Log in to firebase: firebase login 40 Further Reading: Angular Firebase - Deploying an Angular App to Firebase

Slide 41

Slide 41 text

Deploy to Firebase Hosting 1. Initialize Firebase Repo: firebase init 2. Choose the following settings: ○ Choose hosting as the project type ○ Change public folder to dist/ ○ Configure as a single page app ○ Overwrite idnex.html? NO 3. Deploy! Firebase deploy 4. Visit the url in the command line output to see your app 41

Slide 42

Slide 42 text

The Future with Service Workers Part 4 (final) Git Tag: pwa-tutorial-0.4 42

Slide 43

Slide 43 text

The Future is Awesome ● Imagine if you could read your favorite NY Times articles or ● Read your twitter “while you were gone” tweets ● While on the plane! ● Imagine if you could save your Amazon shopping cart and read the product reviews while on train to work in morning ● The next 1 billion users of internet have poor internet connection: think of how this benefits them ● With service workers all this and more is possible 43

Slide 44

Slide 44 text

Mobile vs. Web ● With all these features and push notifications (story for another day), why make a native mobile app? ● See this article for why startups and companies should consider web apps: ○ Tl:dr native apps are hard because of: app store gatekeepers, supporting 2 different platforms (ios, Android), no one wants to download another app, 44

Slide 45

Slide 45 text

What this Means for You ● If starting a company, really consider if building a native mobile app is worth it or is a PWA a better choice ● When building your web app don’t let lack of internet be a constraint, it should be a feature! ○ Hard to compete for users attention when there is internet ○ Imagine if you are one of the few apps that works when there is no internet 45

Slide 46

Slide 46 text

Resources ● Angular Official Service Worker Documentation ● Angular University: Angular Service Workers ● Add Service Worker to Existing Angular App ● Angular Firebase - Deploying an Angular App to Firebase 46

Slide 47

Slide 47 text

Thanks For Watching 47