PWA 入门

PWA 基本介绍

PWA(Progressive Web App)是一种理念,使用多种技术来增强web app的功能,可以让网站的体验变得更好,能够模拟一些原生功能,比如通知推送。在移动端利用标准化框架,让网页应用呈现和原生应用相似的体验。

pwa mdn

PWA特点

  1. 可靠——即时加载,即使在不确定的网络条件下也不会受到影响。
    当用户从主屏幕启动时,service work可以立即加载渐进式Web应用程序,完全不受网络环境的影响。service work就像一个客户端代理,它控制缓存以及如何响应资源请求逻辑,通过预缓存关键资源,可以消除对网络的依赖,确保为用户提供即时可靠的体验。
  2. 快速
    据统计,如果站点加载时间超过 3s,53% 的用户会放弃等待。页面展现之后,用户期望有平滑的体验,过渡动画和快速响应。
  3. 沉浸式体验—— 感觉就像设备上的原生应用程序,具有沉浸式的用户体验。
    渐进式Web应用程序可以安装并在用户的主屏幕上,无需从应用程序商店下载安装。他们提供了一个沉浸式的全屏幕体验,甚至可以重新与用户接触的Web推送通知。

PWA技术点

a). web app manifest

manifest_mdn

web程序应用清单

Web应用程序清单在一个JSON文本文件中提供有关应用程序的信息(如名称,作者,图标和描述)。manifest 的目的是将Web应用程序安装到设备的主屏幕,为用户提供更快的访问和更丰富的体验。

新建 manifest.json文件,

引入,必须在https 或者 http://localhost 运行。 个人是vscodelive Serve插件

  • 常见配置

    name:指定应用名称
    short_name: 应用短名称,主屏显示
    start_url:用户启动程序加载的url
    icons:各个平台icon
    background_color:用户指定的背景颜色
    theme_color:主题色
    display: app显示方式

MDN 范例

    
{
    "name":"测试项目--appp",
    "short_name":"测试1",
    "start_url":"/index.html",
    "icons":[
        {
            "src":"images/1.jpg",
            "size":"144x144",
            "type":"images/jpg"
        }
    ],
    "background_color":"skyblue",
    "theme_color":"yellow",
    "display":"standalone"
}

PWA 入门_第1张图片

b). service worker

前提条件
了解 worker

worker mdn

运行者 Worker 接口是Web Workers API 的一部分,代表一个后台任务,它容易被创建并向创建者发回消息。创建一个运行者只要简单的调用Worker()构造函数,指定一个脚本,在工作线程中执行。临时

let myWorker = new Worker("worker.js");
myworker.addEventListener('message',e=>{  console.log(e)   }),


// worker.js
self.postMessage({data})

简单的注册监听

那正主来了 Service workor

service worker

  • 一旦install,就永久存储,除非unregister
  • 用到的时候唤醒,不用的时候自动休眠
  • 可编程式拦截请求,缓存文件
  • 必须https请求(localhost)

注册步骤

  • window.onload注册
  • navigator对象内置serviceWorker
  • 注意可能低版本兼容性问题 if()
  • 注册service worker,返回的是一个promise对象
    <script>
        window.addEventListener('load',()=>{
            if('serviceWorker' in navigator){
                navigator.serviceWorker.register('./sw.js').then(res=>{
                    console.log(res)
                }).catch(err=>{
                    console.log(err)
                })
            }
        })
    </script>

生命周期
install 会在 service worker 注册成功后触发,主要用于缓存资源
activate 事件会在service worker激活后触发,一般用于删除旧的资源
fetch 发送请求的时候触发

self.addEventListener('install',event=>{

    console.log('install',event)
    // service worker 跳过等待   直接进入activate
    event.waitUntil(self.skipWaiting())
})

self.addEventListener('activate',event=>{
    console.log('activate',event)


    // 表示service worker激活后,立即获取控制器
    event.waitUntil( self.clients.claim())
})

self.addEventListener('fetch',event=>{
    console.log('fetch',event)
})
c). fetch api

关键是 返回的 res为数据流
fetch mdn

	fetch('./data.json').then(res=>{
        console.log(res) // 流
        return res.json()
    }).then(res=>{
        console.log(res)
    })

d) cache storage

cache storage

CacheStorage 接口表示 Cache 对象的存储。它提供了一个 ServiceWorker 、其它类型worker或者 window 范围内可以访问到的所有命名cache的主目录(它并不是一定要和service workers一起使用,即使它是在service workers规范中定义的),并维护一份字符串名称到相应 Cache 对象的映射。

常见方法

CacheStorage.match()
检查给定的 Request 是否是 CacheStorage 对象跟踪的任何 Cache 对象的键,并返回一个resolve为该匹配的 Promise .
CacheStorage.has()
如果存在与 cacheName 匹配的 Cache 对象,则返回一个resolve为true的 Promise .
CacheStorage.open()
返回一个 Promise ,resolve为匹配 cacheName (如果不存在则创建一个新的cache)的 Cache 对象
CacheStorage.delete()
查找匹配 cacheName 的 Cache 对象,如果找到,则删除 Cache 对象并返回一个resolve为true的 Promise 。如果没有找到 Cache 对象,则返回 false.
CacheStorage.keys()
返回一个 Promise ,它将使用一个包含与 CacheStorage 追踪的所有命名 Cache 对象对应字符串的数组来resolve. 使用该方法迭代所有 Cache 对象的列表。

cache mdn

Cache.match(request, options)
返回一个 Promise对象,resolve的结果是跟 Cache 对象匹配的第一个已经缓存的请求。
Cache.matchAll(request, options)
返回一个Promise 对象,resolve的结果是跟Cache对象匹配的所有请求组成的数组。
Cache.add(request)
抓取这个URL, 检索并把返回的response对象添加到给定的Cache对象.这在功能上等同于调用 fetch(), 然后使用 Cache.put() 将response添加到cache中.
Cache.addAll(requests)
抓取一个URL数组,检索并把返回的response对象添加到给定的Cache对象。
Cache.put(request, response)
同时抓取一个请求及其响应,并将其添加到给定的cache。
Cache.delete(request, options)
搜索key值为request的Cache 条目。如果找到,则删除该Cache 条目,并且返回一个resolve为true的Promise对象;如果未找到,则返回一个resolve为false的Promise对象。
Cache.keys(request, options)
返回一个Promise对象,resolve的结果是Cache对象key值组成的数组。

PWA 入门_第2张图片

简易

const CACHE_NAME = 'cache_v2'

// 加载缓存资源
self.addEventListener('install',async event=>{
    const cache = await caches.open(CACHE_NAME)
    await cache.addAll([
        '/',
        '/manifest.json',
        '/images/1.jpg'
    ])
    
    console.log('install',event)
    // service worker 跳过等待   直接进入activate
    await self.skipWaiting()
})

// 主要是清楚缓存
self.addEventListener('activate',async event=>{
    console.log('activate',event)

    const keys = await caches.keys()

    keys.forEach(key => {
        if(key !== CACHE_NAME){
            caches.delete(key)
        }
    })
    // 表示service worker激活后,立即获取控制器
    await self.clients.claim()
})


// 如果数据请求成功就响应成功数据,如果失败,从缓存中取
self.addEventListener('fetch',event=>{
    const req = event.request;

    // 给浏览器响应
    event.respondWith(netWorkFirst(req))  // 是否网络优先情况而定
    
})


// 网络优先
async function netWorkFirst(req){

    try {
       let fresh = await fetch(req)
        return fresh
    } catch (e) {
        // 缓存取
        const cache = await caches.open(CACHE_NAME)
        const cached = await cache.match(req)
        return cached
    }
}
e) notification

通知接口用于向用户配置和显示桌面通知。
noticcation mdn

浏览器默认权限
在这里插入图片描述
Notification.requestPermission() 用于当前页面向用户申请显示通知的权限。

PWA 入门_第3张图片


        if(Notification.permission === 'default'){ // 默认时去请求权限 
            Notification.requestPermission()
        }

        if(!navigator.onLine){
            new Notification('提示', { body: '你当前没有网络'})
        }

        window.addEventListener('online',()=>{
            new Notification('提示', { body : '你已经连上网络'})
        })

PWA 入门_第4张图片

你可能感兴趣的:(H5,JavaScript)