WPA- Progressive Web applications

What is the PWA

Progressive Web applications improve Web APP browsing experience.

manifest

Application manifest

Basic introduction:

  • Web App Manifest is part of the PWA technology collection

  • Web App Manifest allows websites to be installed on the device’s home screen without requiring users to download them through an app store

  • Web App Manifest, which provides information about the application (name, author, icon, description, and so on) in a JSON text file

  • Traditional Web App entry

    • Web site
    • Bookmark, bookmark
    • Direct search
  • Web app manifest:

    • Can be added to the desktop with a unique icon and name
    • There is an interface at startup, avoiding rigid transitions
    • Hide browser-specific UI, such as the address bar, and so on
  • Applicable steps:

    • Create a manifest.json file in the project root directory
    • Introduce the manifest.json file in index.html
    • Common configurations are provided in the manifest.json file
    • You need to access the project over HTTPS or at http://localhost
    • <link rel="manifest" href="manifest.json" />
  • Common Configuration List

    • Name: Specifies the name of the application, the text for the installation banner, and the text for the splash screen
    • Short_name: indicates the short name of the application, which is displayed on the main screen
    • Start_url: Specifies the URL to load when the user starts the application from the device. It can be absolute or relative
    • ICONS: Specify images that can be used as application ICONS in various environments
    • Background_color: background color when the user starts
    • Theme_color: The theme color used to configure the application
    • Display: Specifies the display mode of the Web app
      • Fullscreen: displays in fullscreen
      • standalone
      • minimal-ui

service worker

  • Basic introduction
  • The standard PWA program consists of three parts
    • HTTPS server orhttp://localhost
    • manifest.json
    • service worker
  • Service workers and Web workers
  • Use of Web workers
    • Create: Web Workervar worker = new Worker('work.js')
    • Perform complex calculations in Web work
    • At the end of the web work calculation, passself.postMessage(msg)Send a message to the main thread
    • Main thread passworker.onmessage=function(msg){}Listen to the message
    • The main thread can communicate with the Web worker in the same way
  • The service worker is introduced
    • Once install exists forever, unless manually unregister
    • You can wake up directly when you need it and sleep automatically when you don’t need it
    • Can become interception proxy requests and returns, cache files, cached files can be retrieved by web processes, including network offline state
    • Offline content developers can control
    • It must work in an HTTPS environment
    • Asynchronous implementations, mostly Promise implementations inside
  • Sevice worker Application object
    • Register the service worker in window.onload to prevent competition with other resources
    • The serviceWorker property is built into the Navigator object
    • Service workers are not supported in older browsers, so browser compatibility is required
      • if('serviceWorker in navigator'){}
    • Registration service workernavigator.serviceWorker.register('./sw.js')Returns a Promise object
<script>
  // It can only be used in localhost or HTTPS
  // Register when the page is finished loading
  window.addEventListener("load".() = > {
    // Ability test
    if ("serviceWorker" in navigator) {
      navigator.serviceWorker.register("./sw.js").then((res) = > {
        console.log(res); }); }});</script>
Copy the code
  • The service worker declares cycles

    • The install event is triggered when the service worker is successfully registered and is used to cache resources
    • The Activate event is triggered when a service worker is activated and is used to delete old resources
    • The FETCH event is triggered when a request is sent and is used for caching operations or reading network resources
    • If sw.js changes, the Install event refires
    • The Activate event is triggered after the install event, but if a service worker already exists, it waits until the service worker terminates
    • Can be achieved byself.skipWaiting()Method skips the wait and returns a Promise object
    • Can be achieved byevent.WautUntil()The extended argument to the method is a Promise object that will not terminate the current life cycle function until the promise ends, preventing the browser from stopping the life cycle before a single action
    • After the service worker is activated, it takes effect when the page is refreshed next time and can passself.clients.claim()Live control immediately
self.addEventListener("install".(event) = > {
  console.log("install", event);
});
self.addEventListener("activate".(event) = > {
  console.log("activate", event);
});
self.addEventListener("fetch".(event) = > {
  console.log("fetch", event);
});
Copy the code
self.addEventListener("install".(event) = > {
  console.log("install", event);
  // skipWaiting causes serviceworker to skip the wait and go directly to Activate
  //waitUntil skipWaiting is complete before entering activate
  event.waitUntil(self.skipWaiting());
});
self.addEventListener("activate".(event) = > {
  console.log("activate", event);
  // Indicates the control of the service worker to live immediately after it is activated
  event.waitUntil(self.clients.claim());
}); // The fetch event is triggered when the request is sent
self.addEventListener("fetch".(event) = > {
  console.log("fetch", event);
});
Copy the code

promise

  • Basic applicable
  • Promise is a solution to asynchronous programming that is more powerful than traditional solutions, callback functions, and events
  • Promise can be programmed asynchronously in a chained fashion, eliminating the problem of callback hell
  • The usual static method for Promises
    • Promise.resolve() returns a parsed Promise object with the given value, or if the return value is a Promise object, the Promise object is returned directly
    • Promise.reject() The static function promise.reject () returns a rejected Promise object
    • Promise.all() returns an instance of a Promise until all Promise objects succeed
    • Promise.race(). As long as one of the Promise objects succeeds or fails, the result is either success or failure

async/await

  • Basic applicable
  • The ES2017 (ES8) standard introduces async functions to make asynchronous operations more convenient
  • Async is used to modify a function async function fn(){}, await function returns a promise object
  • Await can only appear in async functions. Await is followed by a promise object to get the result of a successful promise object, or return the value if it is not a promise object
  • Await blocks async function execution
  • An await promise will throw an exception if it fails and you need to use try catch syntax

fetch api

If the service worker wants to send a request, the FETCH API must be applied

Basic use:

fetch("./manifest.json")
  .then((res) = > {
    return res.json();
  })
  .then((data) = > {
    console.log(data);
  });
Copy the code

cache storage

The cacheStorage interface represents the storage of Cache objects and works with the Service worker to Cache resources

  • The cache API is similar to the operation of a database
    • Caches.open(cacheName).then(res=>{}), which opens the cache and returns a Promise to match the Cache object of cacheName, similar to connecting to a database
    • Caches. Key () returns a promise object, including all the cache keys
    • Caches. Delete (key) Deletes the corresponding cache based on the key
  • Cache object:
    • The cache interface provides a storage mechanism for cached pairs of Request/Response objects
    • Cache.put (req,res) treats the request as a key and stores the corresponding response
    • Cache.add (url) initiates a request based on the URL and stores the response
    • Cache.addall (urls) grabs an array of urls and stores the results
    • Cache.match (req) Gets the response corresponding to req

Enable cache:

<! -- index.html -->
<script>
  // Register when the page is finished loading
  window.addEventListener("load".async() = > {// Ability test
    if ("serviceWorker" in navigator) {
      try {
        const registration = await navigator.serviceWorker.register("/sw.js");
        console.log("Registration successful");
      } catch (error) {
        console.log("Registration successful", error); }}});</script>
Copy the code
//sw.js
// It is mainly used to cache content
const CACHE_NAME = "cache_v1";
self.addEventListener("install".async (event) => {
  // Open a cache to get a cache object
  const cache = await caches.open(CACHE_NAME);
  // Wait for cache to store all resources
  await cache.addAll(["/"."/img/icon.png"."/manifest.json"."/index.css"]);
  // Causes the service worker to skip the wait and go directly to Activate
  // Wait for skipWaiting to end before entering activate
  await self.skipWaiting();
});
// Mainly clean up the old cache
self.addEventListener("activate".async (event) => {
  const keys = await caches.keys();
  // Delete the old resource
  keys.forEach((key) = > {
    if (key !== CACHE_NAME) {
      caches.delete(key);
    }
  });
  // Indicates the control of the service worker to live immediately after it is activated
  await self.clients.claim();
});

// The fetch event is triggered when the request is sent
If the request is successful, the response is successful. If the request fails, read the cache
self.addEventListener("fetch".(event) = > {
  // console.log('fetch', event)
  const req = event.request;
  event.respondWith(networkFirst(req));
});
// Network preference
async function networkFirst(req) {
  try {
    // Priority network reads the latest resources
    const fresh = await fetch(req);
    return fresh;
  } catch (e) {
    // read from the cache
    const cache = await caches.open(CACHE_NAME);
    const cached = await cache.match(req);
    returncached; }}Copy the code

notification api

  • Basic use:
  • The Notification interface of the Notification API is used to configure and display desktop notifications to users
  • Notification.permission Obtains the authorization information of the current user
    • Default: the Default is not authorized
    • Denied: Denied cannot be reauthorized
    • Granted: authorized, can be pop-up reminder
  • throughNotification.requestPermission()User authorization can be requested
  • throughnew Notification('title',{body:'',icon:''})Notifications can be displayed
  • Notifications can be displayed in the service worker if authorization is grantedSelf. Registration. ShowNotification (' hello ', {body: 'MSG'})
// Notification message
if (Notification.permission === "default") {
  Notification.requestPermission();
}
if (navigator.onLine) {
  new Notification("Tip", {
    body: "Welcome to The Yerwin ledger ~ this application is a PWA application that supports offline use ~"}); }Copy the code