Github Pages is a web hosting service provided by Github, which can be used to deploy personal blogs or project homeppages. It uses the Jekyll framework as a carrier for file parsing and conversion into static files of web Pages. PWA(Progressive Web Apps) is a concept proposed by Google in recent years. It is committed to using native Web technology to quickly create reliable Web Apps comparable to native application experience. Github Pages is a fast, convenient, free and reliable way to create a personal blog. Enhanced with PWA technology, our blog can be accessed as an application, increasing user viscosity.

What is the PWA

PWA does not refer to any particular technology or tool. Rather, it refers to the methodology of using a range of the latest Web technologies while ensuring that applications in browsers that do not support the new features are not compromised. Progressive means using only a few of these technologies instead of the full set. Most Feers have probably heard of the term, and the technology quickly became popular in the front-end community when the giant Google was pushing it, but if you trace the concept to its earliest incarnation, you have to go back to Progressive Web Apps written by Alex Russell: Escaping Tabs Without Losing Our Soul, the core is to enhance the Web Without Losing its Soul.

About Alex Russell

Ps: *Alex Russell* is one of the founders of the framework [Dojo](https://dojo.io/). Dojo is the first front-end framework I’ve used since I started working on it. The AMD module standard that was so popular a few years ago was derived from Dojo. The inside of the modular, modular and show and logical separation of thoughts, deeply influenced my understanding and the understanding of the front, I have benefited a lot from, it is a pity because it is maintained by IBM * * develops so slowly, on the front end development speed comparable to light blooms in recent years, various frameworks contend in beauty doo-yan, so that less and less people use this framework. However, Dojo 2.0 has been rewritten with the latest TypeScript, Webpack, and other technologies, and is a new framework that I’m looking forward to seeing in the future.

The main improvements brought by PWA are:

  1. Installable – allows users to add web apps to the device’s home screen, just like installing a native app without passing throughApple StoreOr any other app store. Then go straight to the web app.Ps: iOS has supported this feature almost since birth
  2. Offline Capabilities – One of the most important things that Web apps have never been able to match native apps is the ability to access them offline. It is well known that traditional Web pages cannot survive without the Web. But the PWA can go beyond that.
  3. Recall power – Traditional web pages cannot actively push messages to users when they are not open and visited, which leads to a failure to continuously interact with users and improve user retention. PWA uses the latest API to push messages when users are not accessing the application, putting Web applications and native applications on the same footing.
  4. Easy to find – After all, a Web app is a Web page, so it can be found by search engines and has one feature that native apps can’t: it can be easily shared with others via a URL. Mentioned aboveWeb soulOne of them is thisopen.

The technologies currently available for developing PWA applications include:

  • Service Worker – One of the core technologies for offline application access
  • Cache – the second core technology to implement application offline access
  • Fetch API – The third core technology for offline application access
  • App Manifest – Implements the technology for adding applications to the desktop
  • Push API – One of the main technologies for implementing server Push
  • Notifications API – Two of the main technologies used to implement server push

This article does not cover the concept and use of each technology in detail. If you are interested, this article explains how to introduce each feature in PWA step by step in Github Pages.

Github Pages + PWA

The following example uses the Jekyll engine used by Github Pages by default. See here for details.

Service Worker

Speaking of PWA having to mention the Service Worker in the first place, the efficacy of other features depends more or less on enabling it in the first place. We mainly do things during the three life cycles of the Service Worder (events) install, Activate, and FETCH:

Register

A Service Worker is different from normal script code in that all of its code needs to be placed in a separate file and registered to the page through the specified interface.

Assuming we now have a service-worker.js file in the project root directory, we add the following code to the index.html file in the root directory:

<script>
// Register the service worker
if (navigator.serviceWorker) {
  navigator.serviceWorker.register('/service-worker.js', {scope: '/'})}</script>
Copy the code

First determine if the current environment supports Service Worder, and remember that our core is Progressive! The second parameter to the register method, scope, specifies the scope that the Worker can control (as determined by the URL). For example, 🌰 : If scope is set to /sub/, then all requests from the web page to /other/ or /other/foo cannot be intercepted in the Worker fetch event. The default value range is the same as the Service Worker file path.

Install

After registration, the Service Worker starts to execute, first receiving an Install event. We can fetch resources in the install event callback and put them in the cache:

Suppose our blog needs to use two files main.js and main. CSS, respectively, in the js directory and CSS directory, the Service Worker can write:

const CACHE_NAME = 'xlaoyu_blog_1. 0.0';

const URLS = [                // Add URL you want to cache in this list.
  // '/', // If you have separate JS/CSS files, add path to those files here
  '/index.html'.'/css/main.css'.'/js/main.js'
];

// Cache resources
self.addEventListener('install'.function (e) {
  e.waitUntil(
    caches.open(CACHE_NAME).then(function (cache) {
      console.log('installing cache : ' + CACHE_NAME)
      return cache.addAll(URLS);
    }).then(_= > {
      returnself.skipWaiting(); }); ; });Copy the code

E.waituntil – marks the installation state as complete until the incoming Promise is complete

Caches. Open (chche_name) – Opens a cache object. A domain name can have multiple cache objects

Cache.addall (urls) – Automatically requests resources in the background based on the incoming URL, and stores the resource content as value in the last open cache object using the URL as the key.

Self.skipwaiting () – Skip the waiting phase, as explained below.

Intercept request (FETCH)

This event gives our Service Worker the ability to filter or replace all requests from pages in a specified range.

// Respond with cached resources
self.addEventListener('fetch'.function (e) {
  e.respondWith(
    caches.match(e.request).then(function (request) {
      if (request) {
        // If cache exists, return cache directly
        console.log('responding with cache : ' + e.request.url);
        return request;
      } else {
        // The cache does not exist
        console.log('file is not cached, fetching : ' + e.request.url);
        returnfetch(e.request); }}); ; });Copy the code

Activate

This is where we can clean up old or unused caches.

To enter this stage, one of the following two conditions is met:

  • The Service Worker is registered for the first time
  • The Service Worker has been updated, and there are no pages using or using the old WorkerskipWaitingskipwaitingphase

If the contents of the Service Worker file have changed, and the browser retrieves the new file when visiting the site page, it will assume that there has been an update, install the new file and trigger the Install event. However, the old activated Service Worker is still running, and the new Service Worker will enter the waiting state after installation. The new Service Worker does not take effect on the next opened page until all opened pages are closed and the old Service Worker stops automatically.

// Delete outdated caches
self.addEventListener('activate'.function (e) {
  e.waitUntil(
    caches.keys().then(function (keyList) {
      // `keyList` contains all cache names under your username.github.io
      // filter out ones that has this app prefix to create white list
      // Starting with app_prefix returns 0, which is filtered out
      // Therefore, cacheWhitelist contains only the latest key of the current script or the cache added by other scripts
      var cacheWhitelist = keyList.filter(function (key) {
        return key.indexOf(APP_PREFIX);
      });
      // add current cache name to white list
      cacheWhitelist.push(CACHE_NAME);

      return Promise.all(keyList.map(function (key, i) {
        if (cacheWhitelist.indexOf(key) === - 1) {
          console.log('deleting cache : ' + keyList[i] )
          return caches.delete(keyList[i])
        }
      }));
    }).then(function () {
      // Update the clientclients.claim(); })); });Copy the code

Clients.claim () – Makes the page use the new Worker immediately. Normally, a new Service Worker takes effect only after the page is reopened. By combining skipWaiting with this method, the new Worker can take effect immediately.

At this point, a simple Service Worker process has gone through,

Tools for hands

Above, we simulated how to operate the simplest page using the Service Worker. It was very simple and fast. However, if we think about it carefully, things are not so simple in complex scenarios.

  1. A large project may contain hundreds or thousands of static files, so it is obvious that maintaining this list manually is not feasible;
  2. The browser can check at the byte levelService-Worker.jsThe file changes, and then the corresponding operation, but if the Service Worker does not change, it cannot detect whether the cached file has changed and read the latest file. In fact, this problem occurs whether Service workers are used or not. In traditional scenarios, the most common solution is to hash file names. This method can also be used here, but combined with the first point, it is obviously impossible to manually maintain;

Sw-precache – A tool that solves both of these problems by scanning a specified static file directory, calculating the file hash, and then generating service worker files. Please refer to the official document for the opening method. Here are the configurations I used:

const prefix = '_site';

module.exports = {
  staticFileGlobs: [
    '! _site/assets/**/**.*'.'! _site/service-worker.js',
    prefix + '/**/**.html'.// HTML for all pages, article pages (must include)
    prefix + '/js/*.js'.// All js files
    prefix + '/css/*.css'.// All CSS files
    prefix + '/images/**/**.*'.// Personal folder for storing blog related pictures, normally there is no folder
    prefix + '/favicon.ico',
    prefix + '/**/*.json',].stripPrefix: prefix
}
Copy the code

A few caveats:

  1. Why scan_siteDirectory?

    Since the Github Pages page accesses the files in this directory, if you have ever used the Jekyll service to start compiling blogs locally, you will see this in the project root directory_siteDirectory.
  2. Why exclude_site/assets? This directory will be generated locally, but it will not be generated in the formal environment after I post it to Github after testing. Therefore, if this directory is not excluded, the Service Worker will try to cache the files in this directory, which will result in loading error and the whole Worker will be invalid. This is not what we want to see.
  3. What do we need to cache for offline access? HTML files, all pages must use JS, CSS, images, JSON, etc., which do not use CDN proxy.

Actual effect:

Visit www.xlaoyu.info while connected, then disconnect the network and operate on the page (no external link hops). You can see that the interaction is not affected when disconnected.

App Manifest

App Manifest is a technology that enhances the mobile capabilities of Web applications. The idea is that our web pages can be added to the home screen and have almost identical performance to native apps.

First, we add the information to import the manifest file in the head section of the page:

<! -- APP Manifest -->
<link rel="manifest" href="/manifest.json">
Copy the code

Here is my manifest.json file configuration

{
  "scope": "/"."name": "xlaoyu-blog"."short_name": "xlaoyu-blog"."start_url": "/? from=homescreen"."display": "standalone"."description": "The road is long, I will search high and low."."dir": "ltr"."lang": "cn"."orientation": "portrait"."theme_color": "#70B7FD"."background_color": "#fff"."icons": [{
    "src": "images/icon-48x48.png"."sizes": "48x48"."type": "image/png"
  }, {
    "src": "Images/apple - touch - icon - 57 x 57. PNG"."sizes": "57x57"."type": "image/png"
  }, {
    "src": "images/apple-touch-icon-72x72.png"."sizes": "72x72"."type": "image/png"
  }, {
    "src": "images/icon-96x96.png"."sizes": "96x96"."type": "image/png"}}]Copy the code

So we can see how ICONS are configured here.

Note that to add a Web page to the desktop, you need to open the desktop version once in the state of networking to achieve offline access. If you do not open the desktop version once after adding, the “APP” will still be unavailable after disconnecting from the Internet.

Other technologies

Since it is unlikely that Github Pages will need push and other features, which are only needed in real apps, I won’t repeat them here.

conclusion

In fact, in most personal blog or webpage scenarios, whether support offline access, whether can be added to the desktop simulation native application is not so important, can retain users to attract others to visit the core requirements are the content and quality of the article, this attempt is just as a practice purpose.

These are just a few of the applications of PWA, and the combination of so many technologies and extraordinary creativity is sure to lead to more amazing features and functions. Maybe it’s not the best time for the front end, but it must be a more and more wonderful time!

If the above content is wrong, or have other views, please leave a message to discuss.


Reference article:

  • Using_Service_Workers – MDN
  • Pwa-service-worker-zhiwen Studio
  • How do you see the future of Progressive Web Apps? – zhihu

Copyright: Xlaoyu.info