碎片化学习前端之其他(PWA)

前言

PWA 是什么?简而言之,PWA是一种允许客户将网站作为应用程序安装在智能手机的技术。国内小程序横行天下,PWA还有存在可能吗?

PWA

PWA(Progressive Web Apps),渐进式网络应用程序。PWA包含一系列技术方案,如 Web App Mainfest,Service Worker,Push API,Notification API,App Shell,App Skeleton 等。

Web App Mainfest

Web App Mainfest 是支持应用程序添加快捷方式的技术。

  1. Android 配置

    index.html 添加 mainfest.json

    <link rel="mainfest" href="/mainfest.json"></link>
    

    mainfest.json

    {
        "name": "Web Apps", // 应用程序名称
        "short_name": "WA", // 应用简称
        "display": "standalone", // fullScreen standalone minimal-ui browser
        "start_url": "/", // 打开网站地址
        "icons": [{ // 桌面图标
            "src": "/icon.png",
            "sizes": "144*144",
            "type": "image/png",
        }],
        "background_color": "#aaa", // 启动画面颜色
        "theme_color": "#aaa", // 状态栏颜色
    }
    
  2. IOS 配置

    IOS 不支持 mainfest 文件,可以通过 meta/link 私有属性进行设置

    <link rel="apple-touch-icon" href="/icon.png">
    <meta name="apple-mobile-web-app-title" content="应用名称" />
    <!-- 隐藏safari地址栏 -->
    <meta name="apple-mobile-web-app-capable" content="yes" />
    <!-- 设置状态栏颜色 -->
    <meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />
    

Service Worker

Service Worker 是支持应用程序离线访问的技术。

  1. 注册 Service Worker

    index.js

    window.addEventListener('load', async () => {
        if(navigator.serviceWorker) {
            let registration = await navigator.serviceWorker.register('/serviceworker.js')
        }
    })
    
  2. 配置 Service Worker

    serviceworker.js

    // 离线缓存资源
    const CACHE_NAME = 'cache_v' + 0
    const CACHE_LIST = [
        '/',
        '/index.html',
        '/index.js',
        '/index.css',
        '/mainfest.json',
        '/icon.png',
        '/api/list',
    ]
    
    // 拦截请求
    self.addEventListener('fetch', (event) => {
        console.log(event.request.url)
    
        // 静态资源不拦截
        let url = new URL(event.request.url)
        if(url.origin !== self.origin) {
            return
        }
    
        // 缓存策略:请求数据更新缓存
        if(event.request.url.includes('/api')) {
            return event.respondWith(fetchAndSave(event.request).catch(exp => {
                return caches.match(event.request)
            }))
        }
    
        // serviceWorker不支持 ajax,支持 fetch,离线使用缓存
        event.respondWith(fetch(event.request).catch(exp => {
            return caches.match(event.request)
        }))
    
    })
    
    // 跳过安装等待
    self.addEventListener('install', (event) => {
        console.log('第一次安装执行')
    
        // 预先缓存,缓存完成跳过等待
        event.waitUntil(preCache())
    })
    
    // 激活,立即生效(默认不会立即生效)
    self.addEventListener('activate', (event) => {
        console.log('第一次激活执行')
        event.waitUntil(Promise.all([clearCache(), clients.claim()]))
    })
    
    async function fetchAndSave(request) {
        let res = await fetch(request)
        let cres = res.clone()
        let cache = await caches.open(CACHE_NAME)
        await cache.put(request, cres)
        return res
    }
    
    async function preCache() {
        let cache = await caches.open(CACHE_NAME)
        await cache.addAll(CACHE_LIST)
        await self.skipWaiting()
    }
    
    async function clearCache() {
        let keys = await caches.keys()
        return Promise.all(
            keys.map(key => {
                return cache.delete(key)
            })
        )
    }
    

Push API

Push API 是支持服务端向应用程序推送消息的技术,兼容性较差。

  1. 订阅推送

    index.js

    window.addEventListener('load', async () => {
        if(navigator.serviceWorker) {
            let registration = await navigator.serviceWorker.register('/serviceworker.js')
    
            // serviceWork 激活以后再订阅
            await navigator.serviceWorker.ready
            let pushSubscription = await registration.pushManager.subscribe({
                userVisibleOnly: true,
                applicationServerKey: 'key',
            })
    
            pushSubscription // 通过 fetch 传递给服务端,建立链接
        }
    })
    
  2. 监听消息

    serviceworker.js

    self.addEventListener('push', (event) => {
        // event.data
    })
    

Notification API

Notification API 是支持应用程序通知消息的技术,兼容性较差。

serviceworker.js

self.addEventListener('push', (event) => {
    // event.data
    
    self.registration.showNotification(event.data)
})

后记

之前也说了,国内小程序的天下,PWA无用武之地。当然,需求要用的话可以使用 webpack 插件 workbox-webpack-plugin,祝好。

posted @ 2023-05-12 10:54  深巷酒  阅读(11)  评论(0编辑  收藏  举报