JS PWA相关技术

2019-02-26  本文已影响0人  风之化身呀

PWA 全称是渐进式 web 应用,它是用一系列前端技术来实现的,目标是提供类似原生APP一样的体验。主要解决的痛点是:

以下介绍 PWA 相关技术

1、Service Worker

PWA中最重要的一项技术,特点是:

navigator.serviceWorker.register('/sw.js', { scope: '/js' }) // 第二个参数制定 sw.js 管理的范围
// sw.js
const allClients = await clients.matchAll();
allClients.forEach(client => client.postMessage(msg));
// 主 js
if("serviceWorker" in navigator) {
    navigator.serviceWorker.addEventListener("message", function(event) {
        let msg = event.data;
        console.log('message',msg)
    }); 
}

2、主 js => sw.js

// 主 js
navigator.serviceWorker.controller.postMessage({
    type: 1, 
    desc: "remove html cache", 
    url: window.location.href}
);
// sw.js
this.addEventListener("message", function(event) {
    let msg = event.data;
    console.log(msg);
});
// 主 js 注册 serviceWorker
if ('serviceWorker' in navigator) {
    navigator.serviceWorker.register('./sw-demo-cache.js');
}

// sw-demo-cache.js
var VERSION = 'v1';
// 开始缓存
self.addEventListener('install', function(event) {
  this.skipWaiting();  // 避免更新后的 service-worker 处于等待状态
  event.waitUntil(
    caches.open(VERSION).then(function(cache) {
      return cache.addAll([
        './start.html',
        './static/jquery.min.js',
        './static/mm1.jpg'
      ]);
    })
  );
});

// 更新缓存
self.addEventListener('activate', function(event) {
  event.waitUntil(
    caches.keys().then(function(cacheNames) {
      return Promise.all(
        cacheNames.map(function(cacheName) {
          // 如果当前版本和缓存版本不一致
          if (cacheName !== VERSION) {
            return caches.delete(cacheName);
          }
        })
      );
    })
  );
});

// 捕获请求并返回缓存数据
self.addEventListener('fetch', function (event) {
  event.respondWith(
    caches.match(event.request)
      .then(function (resp) {
        if (resp) {
          console.log(new Date(), 'fetch ', event.request.url, '有缓存,从缓存中取')
          return resp
        } else {
          console.log(new Date(), 'fetch ', event.request.url, '没有缓存,网络获取')
          return fetch(event.request)
            .then(function (response) {
              return caches.open(VERSION).then(function (cache) {
                cache.put(event.request, response.clone())
                return response
              })
            })
        }
      })
  )
})


2、Cache和CacheStorage

caches 缓存库一般以request 为key , response为value

caches.open(CACHE_NAME);
// 请求资源并添加到缓存里面去
caches.open(CACHE_NAME).then(cache => {
   cache.addAll(cacheResources);
   // cache.put(request, resource);
})
caches.match(event.request).then(response => {
   // cache hit
   if (response) {
       return response;
   }
})
caches.open(CACHE_NAME).then(cache => {
     console.log("delete cache " + url);
     cache.delete(url, {ignoreVary: true});
 });
3、Web App Manifest添加桌面入口

在项目根目录下准备一个 manifest.json 文件,可以实现用户首次访问网页时提示在桌面创建网页入口icon,以后直接通过桌面的icon就可以直接访问网页了。
注意:只有至少已经访问网站两次、访问至少间隔五分钟时才可以将网络应用添加到主屏幕上。

  "short_name": "人人FED", // 桌面应用的名字
  "name": "人人网FED,专注于前端技术",  // 启动时欢迎语
  "icons": [ // 启动图标
    { 
      "src": "/html/app-manifest/logo_48.png",
      "type": "image/png",
      "sizes": "48x48"
    },
    {
      "src": "/html/app-manifest/logo_96.png",
      "type": "image/png",
      "sizes": "96x96"
    },
    {
      "src": "/html/app-manifest/logo_192.png",
      "type": "image/png",
      "sizes": "192x192"
    },
    {
      "src": "/html/app-manifest/logo_512.png",
      "type": "image/png",
      "sizes": "512x512"
    }
  ],
  "start_url": "/?launcher=true",   // 这个地址要被 service worker 缓存起来
  "display": "standalone", // 启动后隐藏浏览器地址栏
  "background_color": "#287fc5",
  "theme_color": "#fff"
}

然后在 html 文件里引入该文件

    
<link rel="manifest" href="/html/app-manifest/manifest.json">
4、消息提醒与信息推送
// 1、ask for permission
Notification.requestPermission(permission => {  
  console.log('permission:', permission);
});

// 2、display notification
displayNotification(msg)
function displayNotification(msg) {  
  if (Notification.permission == 'granted') {
    navigator.serviceWorker.getRegistration()
      .then(registration => {
        registration.showNotification(msg);
      });
  }
}

sw.js

self.addEventListener('notificationclick', event => {  
  // 消息提醒被点击的事件
  event.waitUntil(clients.openWindow('https://baidu.com'))
});

self.addEventListener('notificationclose', event => {  
  // 消息提醒被关闭的事件
});
参考
上一篇 下一篇

猜你喜欢

热点阅读