PWA渐进式web应用
PWA(Progressive Web App)是一种理念,使用多种技术来增强web app的功能,可以让网站的体验变得更好,能够模拟一些原生功能,比如通知推送。在移动端利用标准化框架,让网页应用呈现和原生应用相似的体验。
PWA核心技术
- web app manifest
 - service worker
 - promise/async/await
 - fatch api
 - Cache storage
 - 常见缓存策略
 - notification
 
PWA四个核心内容
- manifest.json
 - serviceWork
 - cacheStrorage
 - notification
 
1、manifest
- pwa技术集合的一部分
 - 让网站安装到设备主屏幕上,不需要用户在商城下载
 - 在json文件中提供有关应用的信息
 - 启动页面避免生硬过度
 - 隐藏浏览器相关的UI 比如地址栏等
 
注意点
- manifest.json 配置
 - index.html 中引入manifest.json
 - 需要https或者http://localhost下访问
 
常见配置
- name: 项目名称
 - short_name:短名称,用于主屏幕显示
 - start_url:设备应用加载的url 可以使绝对或者相对路径
 - icons : 应用图标144X144
 - background_color:启动动画背景色
 - theme_color:应用程序主题背景色
 - dispay:app显示模式 fullcreen全屏 standalone minimal-ui
 
{
    "name":"电影App",
    "short_name":"app",
    "start_url":"/index.html",
    "icon":[{
        "src":"icons/icon_fro.png",
        "sizes":"144x144",
        "type":"image/png"
    }],
    "background_color":"skyblue",
    "theme_color":"yellow",
    "display":"standalone"
}
2、service worker
- 标准的PWA包括3个部分
https或http://localhost
manifest.json
service work - 做离线缓存
 
web work使用
- 创建web worker var worker = new Worker('work.js')
 - 在web work 中进行复杂计算
 - web work计算结束 通过self.postMessage(msg)给主线程发消息
 - 主线程通过 worker.onMessage = function(msg) 监听消息
 - 主线程可以用同样的方式给web worker进行通讯
 
service worker
- web work 临时的,每次事情不能持久存下来。
 - servive work 类似于代理服务器,存在缓存里
 
- 一旦install ,永久存在,除非被手动unregister
 - 用到的时候唤醒,不用自动休眠
 - 必须https环境下工作
 - 异步实现,内不通过Promise实现
 - 可编程链接代理请求和返回,缓存文件,缓存的文件可以被网页进程取到(包括网络离线状态)
 
service worker使用步骤
- window.onload 中注册service worker ,放在与其他资源竞争
 - navigator对象中内置了serviceWorker属性
 - service worker在老版本不支持,需要进行浏览器兼容 if('serviceWorker' in navigator){}
 - 注册service worker navigator.serviceWorker.register('./sw.js')返回一个promise对象
 
service worker生命周期事件
- install: 注册成功触发,用户缓存资源
 - activate:激活时触发,删除旧的资源
 - fetch 发送请求时触发,操作缓存读取网络资源
 
fetch Api
config常见参数
body
headers
methods
index.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <!-- 引入清单文件 -->
    <link rel="manifest" href="manifest.json">
</head>
<body>
    <h1>hello word</h1>
    <!-- web worker -->
    <script>
        const worker = new Worker('worker.js')
        worker.addEventListener('message', e => {
            console.log(e.data)
        })
    </script>
    <!-- service worker -->
    <script>
        // 1.需要网页加载完成注册
        window.onload = () => {
            // 2.能力监测
            if ('serviceWorker' in navigator) {
                navigator.serviceWorker.register('./sw.js').then(res => {
                    console.log(res)
                })
            }
        }
    </script>
</body>
</html>
webwork.js
// 独立的进程,不能做dom操作
let total = 0
for(var i=0;i<1000000;i++){total+=i}
// 发消息给主线程,把结果给他
self.postMessage({total:total})
sw.js (serviceWorker)
console.log('service注册')
self.addEventListener('install', e => {
    console.log(e)
    /*
     跳过等待,直接到activite状态 是一个promise
      self.skipWaiting()
     */
    // 等待skipWaiting结束,activite状态 是一个promise
    e.waitUntil(self.skipWaiting())
})
self.addEventListener('activate', e => {
    //   表示service work激活后,利可获取控制权
    e.waitUntil(self.ClientRectList.claim())
})
self.addEventListener('fatch', e => {
    console.log(e)
})
3、cacheStorage基本使用
- cache对象的存储,配合service work使用
 
api类似于数据库操作
- caches.open(name).then(function(){}):用于打开缓存
 - caches.keys(数据库名):返回一个promise
 - caches.delete(数据库)
 
cache常用方法
cache接口缓存的request/response对象提供存储机制
- cache.put(req,res)把请求当成key,把相应存储起来
 - cache.add(url) 根据url请求,吧响应结果存储起来
 - cache.addAll(urls)抓取url数组,把结果存起来
 - cache.match(req)获取req对应的response
index.html 
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <!-- 引入清单文件 -->
    <link rel="manifest" href="manifest.json">
</head>
<body>
    <h1>hello word</h1>
    <script>
        window.addEventListener('load', async()=>{
            if('serviceWorker' in navigator){
                try {
                    const registration=await navigator.serviceWorker.register('./sw.js')
                    console.log('成功')
                } catch (error) {
                    console.log('失败')
                }
            }
        })
    </script>
</body>
</html>
sw.js
// 注册serviceWorker时间
const CACHENAME = 'chache_v1'
// 缓存内容
self.addEventListener('install', async (e) => {
    const cache = await caches.open(CACHENAME)
    await cache.addAll([
        '/',
        '/icons/icon_fro.png',
        'manifest.js'
    ])
    e.waitUntil(self.skipWaiting())
})
// 清除就得缓存
self.addEventListener('activate', async e => {
    const keys = await caches.keys()
    keys.forEach(key => {
        if (key == CACHENAME) {
            caches.delete(key)
        }
    })
    e.waitUntil(self.clients.claim())
})
// 请求时间触发
// 能请求:请求
// 不能请求:读取cachesStorage
self.addEventListener('fetch', e => {
    // 请求对象
const req=e.request
// 给浏览器响应
e.respondWith(networkFirst(req))
})
// 网络有限
async function networkFirst(req){
    try {
        const fresh=await fetch(req)
        return fresh
    } catch (error) {
        // 去缓存读取
        const cache=await caches.open(CACHENAME)
        const cached=await cache.match(req)
        return cached
    }
}
4、notiication 通知
- 配置桌面通知的
 - Notification.permisin 可以获得用户的授权情况
 
- default:未授权
 - denied:拒绝
 - granted:授权
 
- Notification.requestPermission() 请求用户授权
 - new Notification(title,{body:''}) 给个通知
 
index.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <!-- 引入清单文件 -->
    <link rel="manifest" href="manifest.json">
</head>
<body>
    <h1>hello word</h1>
    <script>
        window.addEventListener('load', async()=>{
            if('serviceWorker' in navigator){
                try {
                    const registration=await navigator.serviceWorker.register('./sw.js')
                    console.log('成功')
                } catch (error) {
                    console.log('失败')
                }
            }
        })
        // 判断是否联网
        if(Notification.permission=='default'){
            // 请求提示权限
            Notification.requestPermission()
        }
        if(!navigator.onLine){
            new Notification('提示',{body:'当前没有网'})
        }
        window.addEventListener('online',e=>{
            new Notification('提示',{body:'又忘了,请刷新访问最新数据'})
        })
    </script>
</body>
</html>
静态资源缓存优先,动态数据请求有限
PWA渐进式web应用的更多相关文章
- PWA 渐进式Web应用程序 - 解释
		
想象一下,如果一个网站上所有的功能都能够作为一个移动应用程序为用户所用——任何设备上都可以使用.可接收所有的通知.离线模式可用,为了实现这个愿景,2015年,谷歌创造了渐进式Web应用程序(PWA). ...
 - 关于PWA ( Progressive web apps )
		
渐进式Web应用程序使用现代Web API以及传统的渐进式增强策略来创建跨平台Web应用程序.这些应用程序无处不在,并提供多种功能,使其具有与本机应用程序相同的用户体验优势.这套文档告诉您需要了解的所 ...
 - 渐进式Web应用(PWA)入门教程(上)
		
最近关于渐进式Web应用有好多讨论,有一些人还在质疑渐进式Web应用是否就是移动端未来. 但在这篇文章中我并不会将渐进式APP和原生的APP进行比较,但有一点是可以肯定的,这两种APP的目标都是使用户 ...
 - 渐进式Web应用(PWA)入门教程(下)
		
上篇文章我们对渐进式Web应用(PWA)做了一些基本的介绍. 渐进式Web应用(PWA)入门教程(上) 在这一节中,我们将介绍PWA的原理是什么,它是如何开始工作的. 第一步:使用HTTPS 渐进式W ...
 - (转)PWA(Progressive Web App)渐进式Web应用程序
		
PWA 编辑 讨论 PWA(Progressive Web App)是一种理念,使用多种技术来增强web app的功能,可以让网站的体验变得更好,能够模拟一些原生功能,比如通知推送.在移动端利用标准化 ...
 - 什么是渐进式Web App(PWA)?为什么值得关注?
		
转载自:https://blog.csdn.net/mogoweb/article/details/79029651 在开始PWA这个话题之前,我们先来看看Internet现状. 截至2017年1月, ...
 - 渐进式Web应用(PWA)
		
什么是渐进式Web应用? 渐进式Web应用是一种全新的Web技术,让Web应用和原生APP的体验相近或一致. 渐进式Web应用它可以横跨Web技术及Native APP开发的解决方案,对于开发者的优势 ...
 - 开发一个渐进式Web应用程序(PWA)前都需要了解什么?
		
转载请注明出处:葡萄城官网,葡萄城为开发者提供专业的开发工具.解决方案和服务,赋能开发者. 原文出处:https://dzone.com/articles/how-to-build-a-progres ...
 - 试着给VuePress添加渐进式Web应用(PWA)支持,基于vuepress/plugin-pwa,点亮离线访问
		
背景 有时候,我们也希望VuePress构建的文档中心能支持离线访问,这时候我们需要给他添加渐进式Web应用(PWA,Progressive Web App)的支持,根据官方文档指引,我们可以借助插件 ...
 
随机推荐
- 合宙Luat | Cat.1 Socket数据收不到?学会两招不掉线
			
1 服务器收不到Socket数据的原因 Socket是大家使用Cat.1模块常用的功能之一,但Cat.1模块不是直接跟服务器连接,而是通过NAT(即网络地址转换)与服务器连接. 一个会话建立后会在NA ...
 - DOS命令行(7)——Windows网络检测与诊断
			
ping ping 命令的作用是通过发送"网际控制报文协议(ICMP)"回响请求消息来验证另一台TCP/IP计算机的IP级连接状态,回响应答消息的接收情况将和返回过程的次数一起显示 ...
 - 详解Redis主从复制原理
			
文章首发于公众号 "蘑菇睡不着" 前言 Redis 的主从复制和 MySQL 差不多,主要起着 数据备份,读写分离等作用.所以说主从复制对 Redis 来说非常重要,而无论是面试还 ...
 - 最多能创建多少个 TCP 连接?
			
我是一个 Linux 服务器上的进程,名叫小进. 老是有人说我最多只能创建 65535 个 TCP 连接. 我不信这个邪,今天我要亲自去实践一下. 我走到操作系统老大的跟前,说: "老操,我 ...
 - 技术如何转产品01——1+1>2?
			
当业务复杂到一定阶段的时候,效率问题会首当其冲,基本解法是化整为零.分赛道,对应的产物可以是子公司>>事业部>业务单元>项目组. 好处是目标聚焦.所以问题也会聚焦,工作内容闭 ...
 - Kubernetes自动伸缩pod-HPA
			
在运维中,虽然能预先知道负载何时会飙升,或者如果负载的变化是较长时间内逐渐发生的,手动扩容也是可以接受的,但指望靠人工干预来处理突发而不可预测的流量增长,仍然不够理想. 幸运的是,Kubernetes ...
 - k8s-生产环境部署django项目k8s-dashboard管理系统
			
1. k8s-生产环境部署django项目k8s-dashboard管理系统 gitee地址: https://gitee.com/scajy/django-k8s-dashboard.git 部署架 ...
 - Devexpress-WPF初体验
			
最近使用wpf devexpress做一个wpf小项目,中间遇到了一些问题,这里记录下,同时也跟大家分享分享 1.devexpress安装 devexpress提供了很多控件,特别是各种形式的数据列表 ...
 - 微信小程序  添加左边固定浮动框
			
view: <!-- 悬浮框 --> <view class="v-fixed-title1"> <view class="v-fixed- ...
 - Linux系统下安装MongoDB
			
下载安装包 去MongoDB官网https://www.mongodb.com/try/download/community,下载社区版的安装包: 我的Linux系统是CentOS 7.5版本的,通常 ...