PWA,Progressive Web App(渐进式web应用),PWA技术可以将web应用具备接近原生应用的特性和用户体验,无需额外安装,支持离线缓存,消息推送等功能

PWA由Service Worker,Promise,fetch,cache Api,Notification Api等技术组成

Service Worker:服务工作线程,独立于主线程,常驻内存,代理网络请求,依赖HTTPS通信

注册Service Worker

navigator.serviceWorker.register('./sw.js',{scope: '/'}).then(
    registration => {
        console.log(registration)
    },error => {
        console.error(error)
    }
)
window.onload = function() {
    document.body.append('PWA!')
}

sw.js

const cachename = 'v1'
self.addEventListener('install', function (event) {
    console.log('install',event)
    // 安装新的Service Worker脚本时触发,只有Service Worker脚本不同,会认为是不同的Service Worker版本
    event.waitUntil(new Promise(resolve =>{
        setTimeout(resolve, 1000) // 安装新的Service Worker脚本后等待1秒后激活该脚本
    }))
    // event.waitUntil(self.skipWaiting) // 强制停止老的Service Worker,激活启动新的Service Worker,只要有更新就激活新的
    event.waitUntil(caches.open(name).then(cache =>{
        cache.addAll([
            '/',
            './1.img'
        ])
    })) // 开启cache api缓存系统
})
self.addEventListener('activate', function (event) {
    console.log('activate',event)
    // 激活新的Service Worker脚本事件
    event.waitUntil(self.clients.claim())
    event.waitUntil(caches.keys().then(cacheNames =>{
        return Promise.all(cacheNames.map(cacheNames =>{
            if(cacheNames !== cachename){
                caches.delete(cacheNames) // 当前缓存名称不等于设置的缓存名称时,清除缓存,重新获取资源
            }
        }))
    }))
})
self.addEventListener('fetch', function (event) {
    console.log('fetch',event)
    // 获取资源请求事件,例如增加外链
    event.respondWith(caches.open(cachename).then(cache => {
        return cache.match(event.request).then(response =>{
            if(response){
                return response // 命中缓存则直接使用缓存
            }
            return fetch(event.request).then(response =>{
                cache.put(event.request,response.clone())
                // 没有命中则获取该资源
                return response
            })
        })
    }))
})

manifest.json:让web应用具备app的效果,例如logo,启动页面

{
    "name": "hallo",
    "short_name": "你好",
    "display": "standalone",
    "orientation": "landscape",
    "start_url": "/",
    "theme_color": "purple",
    "background_color": "purple",
    "icons": [
        {
            "src": "logo.jpg",
            "sizes": "48x48",
            "type": "image/jpg"
        },
        {
            "src": "logo1.jpg",
            "sizes": "144x144",
            "type": "image/jpg"
        }
    ]
}

Notification消息推送

查看授权

Notification.permission

有3个值,在浏览器默认为default,当同意时,为granted,当不同意时,为denied

在Service Worker中,默认为denied,因为Service Worker不能弹出授权请求,必须先在浏览器中同意后,Service Worker只能发送通知

请求授权

Notification.requestPermission().then(permission => console.log(permission))

发送通知

new Notification(‘hallo word’, {body: ‘hallo’})

在Service Worker发送通知

self.registration.showNotificatio(‘hallo word’)

成熟的PWA插件,workbox