Upgrade to Pro — share decks privately, control downloads, hide ads and more …

How to Build Websites that work without Interne...

How to Build Websites that work without Internet Using Angular, Service Workers and Firebase

In this article, you will learn the theory of how service workers work. I provide a short tutorial to apply that theory to make a website that runs without the internet. Finally, I’ll discuss what this means for you and the future of the internet.

Tomiwa Ademidun

October 03, 2018
Tweet

More Decks by Tomiwa Ademidun

Other Decks in Technology

Transcript

  1. Let’s Keep in Touch: Building a Website that works without

    Internet Using Angular, Service Workers and Firebase Tomiwa Ademidun 1
  2. 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
  3. Different Formats of this Talk This tutorial is available as

    a... 1. Slideshow 2. Video 3. Blog 4. Podcast 5. Source Code 3
  4. Theory What’s an offline first-web app??? What’s a service worker???

    Why should I care??? Is there free food after this??? 4
  5. 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
  6. 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
  7. 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
  8. No Internet, No Problem With internet Without internet: metaphorically “Raise

    your hand” if you knew you could use Google Drive without internet? 11
  9. 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
  10. • 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
  11. 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
  12. 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
  13. 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
  14. 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
  15. 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
  16. 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
  17. 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}),]
  18. 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
  19. 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
  20. 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
  21. 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
  22. 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)
  23. 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
  24. 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
  25. 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
  26. 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
  27. 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
  28. 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
  29. 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
  30. 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
  31. 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
  32. 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
  33. 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
  34. 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