JavaScript深入理解-PWA渐进式应用
WPA-渐进式 web 应用
PWA 是什么
渐进式 Web 应用,提升 web app 浏览体验。
manifest
应用程序清单
基本介绍:
web app manifest
是 PWA 技术集合中的一部分web app manifest
可以让网站安装到设备的主屏幕,而不需要用户通过应用商店下载web app manifest
,在一个 JSON 文本文件中提供有关应用程序的信息(名称,作者,图标和描述等等)传统的 web app 入口
- 网站
- 书签,收藏夹
- 直接搜索
Web app manifest:
- 可以添加到桌面,有唯一的图标和名称
- 有启动时的界面,避免生硬的过渡
- 隐藏浏览器相关的 UI,比如地址栏等等
适用步骤:
- 在项目根目录创建一个 manifest.json 文件
- 在 index.html 引入 manifest.json 文件
- 在 manifest.json 文件中提供常见的配置
- 需要在 https 协议或者在 http://localhost 下访问项目
<link rel="manifest" href="manifest.json" />
常见配置清单
- name:应用的指定名称,安装横幅的文字,启动画面的文字
- short_name:应用的短名称,用于主屏幕显示
- start_url:指定用户从设备启动应用程序时加载的 URL。可以是绝对路径和相对路径
- icons:用于指定可在各种环境中用作应用程序图标的图像
- background_color:用户启动时的背景色
- theme_color:用于配置应用程序的主题颜色
- display:用于指定 web app 的显示模式
- fullscreen:全屏显示
- standalone
- minimal-ui
service worker
- 基本介绍
- 标准的 PWA 程序,包括 3 个部分
- https 服务器或者
http://localhost
- manifest.json
- service worker
- https 服务器或者
- service worker 和 web worker
- web worker 的使用
- 创建:web worker
var worker = new Worker('work.js')
- 在 web work 中进行复杂的计算
- 在 web work 计算结束,通过
self.postMessage(msg)
给主线程发消息 - 主线程通过
worker.onmessage=function(msg){}
监听消息 - 主线程也可以用同样的方式给 web worker 进行通讯
- 创建:web worker
- service worker 介绍
- 一旦 install 就会永远存在,除非手动 unregister
- 用到的时候可以直接唤醒,不用的时候 自动睡眠
- 可以变成拦截代理请求和返回,缓存文件,缓存的文件可以被网页进程取到,包括网络离线状态
- 离线内容开发者可控
- 必需在 HTTPS 环境下才能工作
- 异步实现,内部大都是 Promise 实现
- sevice worker 适用对象
- 在 window.onload 中注册 service worker,防止与其他资源竞争
- navigator 对象中内置了 serviceWorker 属性
- service worker 在老版本的浏览器中不支持,需要进行浏览器兼容
if('serviceWorker in navigator'){}
- 注册 service worker
navigator.serviceWorker.register('./sw.js')
,返回一个 promise 对象
<script>
//需要在localhost 或者 HTTPS中才能使用
// 网页加载完成时注册
window.addEventListener("load", () => {
// 能力检测
if ("serviceWorker" in navigator) {
navigator.serviceWorker.register("./sw.js").then((res) => {
console.log(res);
});
}
});
</script>
service worker 声明周期
- install 事件会在 service worker 注册成功时候触发,主要用于缓存资源
- activate 事件会在 service worker 激活的时候触发,主要用于删除旧的资源
- fetch 事件会在发送请求的时候触发,主要用于操作缓存或者读取网络资源
- 如果 sw.js 发生了改变,install 事件会重新触发
- activate 事件会在 install 事件后触发,但是如果现在已经存在 service worker,就会处于等待状态直到 service worker 终止
- 可以通过
self.skipWaiting()
方法跳过等待,返回一个 promise 对象 - 可以通过
event.WautUntil()
方法扩的参数是一个 promise 对象,会在 promise 结束后才会结束当前生命周期函数,防止浏览器在一步操作之前就停止了生命周期 - service worker 激活后,会在下一次刷新页面的时候生效,可以通过
self.clients.claim()
立即活的控制权
self.addEventListener("install", (event) => {
console.log("install", event);
});
self.addEventListener("activate", (event) => {
console.log("activate", event);
});
self.addEventListener("fetch", (event) => {
console.log("fetch", event);
});
self.addEventListener("install", (event) => {
console.log("install", event);
// skipWaiting 会让serviceworker跳过等待,直接进入activate
//waitUntil 等待skipWaiting结束才进入到activate
event.waitUntil(self.skipWaiting());
});
self.addEventListener("activate", (event) => {
console.log("activate", event);
// 表示service worker激活后,立即活的控制权
event.waitUntil(self.clients.claim());
}); //fetch事件会在请求发送的时候触发
self.addEventListener("fetch", (event) => {
console.log("fetch", event);
});
promise
- 基本适用
- Promise 是异步编程的一种解决方案,比传统的解决方法,回调函数和事件更强大
- Promise 可以以链式的方式来进行异步编程,解决了回调地狱的问题
- Promise 常用的静态方法
- Promise.resolve()返回一个解析过带着给定值的 Promise 对象,如果返回值是一个 Promise 对象,则直接返回这个 Promise 对象
- Promise.reject()静态函数 Promise.reject()返回一个被拒绝的 Promise 对象
- Promise.all() 返回一个 Promise 实例,等所有 promise 对象都成功了,才成功
- Promise.race()竞速,只要有一个 Promise 对象成功了或者失败了,结果就是成功或者失败了
async/await
- 基本适用
- ES2017(ES8)标准引入了 async 函数,使得异步操作变得更加方便
- async 用于修饰一个函数 async function fn(){},await 函数会返回一个 promise 对象
- await 只能出现在 async 函数中,await 后面跟一个 promise 对象,用于获取 promise 对象成功的结果,如果不是 promise 对象,直接返回值
- await 会阻塞 async 函数的执行
- await 后面的 promise 如果没有成功,那么会抛出异常需要用 try catch 语法
fetch api
在 service worker 如果想要发送请求,必需适用 fetch api
基本使用:
fetch("./manifest.json")
.then((res) => {
return res.json();
})
.then((data) => {
console.log(data);
});
cache storage
cacheStorage 接口表示 Cache 对象的储存,配合 service worker 来实现资源的缓存
- cache api 类似于数据库的操作
- caches.open(cacheName).then(res=>{}),用于打开缓存,返回 一个匹配 cacheName 的 cache 对象的 Promise,类似于连接数据库
- caches.key() 返回一个 promise 对象,包括所有的缓存 key
- caches.delete(key) 根据 key 删除对应的缓存
- cache 对象常用方法:
- cache 接口为缓存的 Request/Response 对象对提供存储机制
- cache.put(req,res)把请求当成 key,并且把对应的响应存储起来
- cache.add(url)根据 url 发起请求,并且吧响应结果储存起来
- cache.addAll(urls) 抓取一个 url 数组,并且把结果都储存起来
- cache.match(req) 获取 req 对应的 response
开启缓存:
<!-- index.html -->
<script>
// 网页加载完成时注册
window.addEventListener("load", async () => {
// 能力检测
if ("serviceWorker" in navigator) {
try {
const registration = await navigator.serviceWorker.register("/sw.js");
console.log("注册成功");
} catch (error) {
console.log("注册成功", error);
}
}
});
</script>
//sw.js
// 主要用来缓存内容
const CACHE_NAME = "cache_v1";
self.addEventListener("install", async (event) => {
// 开启一个cache 得到一个cache对象
const cache = await caches.open(CACHE_NAME);
// 等待cache把所有的资源存储
await cache.addAll(["/", "/img/icon.png", "/manifest.json", "/index.css"]);
// 会让service worker跳过等待,直接进入activate
// 等待skipWaiting结束才进入到activate
await self.skipWaiting();
});
// 主要清除旧的缓存
self.addEventListener("activate", async (event) => {
const keys = await caches.keys();
// 判断key 删除旧的资源
keys.forEach((key) => {
if (key !== CACHE_NAME) {
caches.delete(key);
}
});
// 表示service worker激活后,立即活的控制权
await self.clients.claim();
});
// fetch事件 会在请求发送的时候触发
// 判断资源是否能够请求成功,如果能请求成功,就响应成功的结果,如果断网,请求失败了,读取cache缓存即可
self.addEventListener("fetch", (event) => {
// console.log('fetch', event)
const req = event.request;
event.respondWith(networkFirst(req));
});
// 网络优先
async function networkFirst(req) {
try {
// 优先网络读取最新的资源
const fresh = await fetch(req);
return fresh;
} catch (e) {
// 去缓存中读取
const cache = await caches.open(CACHE_NAME);
const cached = await cache.match(req);
return cached;
}
}
notification api
- 基本使用:
- Notification API 的通知接口用于向用户配置和显示桌面通知
- Notification.permission 可以获取当前用户的授权情况
- Default:默认,未授权
- Denied:拒绝的,拒绝无法再次授权
- Granted:授权的,可以弹窗提醒
- 通过
Notification.requestPermission()
可以请求用户的授权 - 通过
new Notification('title',{body:'',icon:''})
可以显示通知 - 在授权通过得情况下,可以在 service worker 中显示通知
self.registration.showNotification('你好',{body:'msg'})
// 通知消息
if (Notification.permission === "default") {
Notification.requestPermission();
}
if (navigator.onLine) {
new Notification("提示", {
body: "欢迎使用耶温记账本~,此应用为PWA应用支持离线使用~",
});
}
JavaScript深入理解-PWA渐进式应用的更多相关文章
- Javascript中理解发布--订阅模式
Javascript中理解发布--订阅模式 阅读目录 发布订阅模式介绍 如何实现发布--订阅模式? 发布---订阅模式的代码封装 如何取消订阅事件? 全局--发布订阅对象代码封装 理解模块间通信 回到 ...
- 第一百二十九节,JavaScript,理解JavaScript库
JavaScript,理解JavaScript库 学习要点: 1.项目介绍 2.理解JavaScript库 3.创建基础库 从本章,我们来用之前的基础知识来写一个项目,用以巩固之前所学.那么,每个项目 ...
- 《javascript个人理解,个人整理。》
万事开头难. 本人做前端工程师,已几年,没有特别大的,已文字方式去做总结. 前段时间,早已经想好,但是迟迟没有去下笔!好在现在陆陆续续的写下去. 我知道这是一个很大的工程,但是我还是想做下去,不为别的 ...
- 【转】Javascript中理解发布--订阅模式
Javascript中理解发布--订阅模式 阅读目录 发布订阅模式介绍 发布---订阅模式又叫观察者模式,它定义了对象间的一种一对多的关系,让多个观察者对象同时监听某一个主题对象,当一个对象发生改变时 ...
- JavaScript深入理解sort()方法
一. 基本用法 let arr1 = [3, 5, 7, 1, 8, 7, 10, 20, 19] console.log(arr1.sort()) // [1, 10, 19, 20, 3, 5, ...
- javascript深入理解js闭包(转)
javascript深入理解js闭包 转载 2010-07-03 作者: 我要评论 闭包(closure)是Javascript语言的一个难点,也是它的特色,很多高级应用都要依靠闭包实现. ...
- PWA 渐进式Web应用程序 - 解释
想象一下,如果一个网站上所有的功能都能够作为一个移动应用程序为用户所用——任何设备上都可以使用.可接收所有的通知.离线模式可用,为了实现这个愿景,2015年,谷歌创造了渐进式Web应用程序(PWA). ...
- javascript的理解及经典案例
js的简介: JavaScript是一种能让你的网页更加生动活泼的程式语言,也是目前网页中设计中最容易学又最方便的语言. 你可以利用JavaScript轻易的做出亲切的欢迎讯息.漂亮的数字钟.有广告效 ...
- javascript深入理解js闭包
一.变量的作用域 要理解闭包,首先必须理解Javascript特殊的变量作用域. 变量的作用域无非就是两种:全局变量和局部变量. Javascript语言的特殊之处,就在于函数内部可以直接读取全局变量 ...
随机推荐
- windows10 WSL
搭建WSL linux下的home目录,映射windows的目录地址 用户家目录 ➜ ~ pwd /home/ajanuw C:\Users\ajanuw\AppData\Local\Packages ...
- Flutter Android Toast Message(flutter访问Android Toast Message)
原文 Android Toast通知可用于向用户发送快速消息,并在几秒钟后消失. 但是当涉及Flutter时,没有直接的方式来显示这些Toast消息.因此,我们需要找到一种替代方法来实现它.在这种情况 ...
- [转]ubuntu系统重新分区、根目录扩容
原文地址:https://blog.csdn.net/code_segment/article/details/79237500,转载主要方便随时查阅,如有版权要求,请及时联系. gparted是一款 ...
- 从微信小程序到鸿蒙js开发【12】——storage缓存&自动登录
鸿蒙入门指南,小白速来!从萌新到高手,怎样快速掌握鸿蒙开发?[课程入口] 正文: 在应用开发时,我们常需要将一些数据缓存到本地,以提升用户体验.比如在一个电商的app中,如果希望用户登录成功后,下次打 ...
- clipse中mybatis的xml配置文件代码提示
编写mybatis的xml文件时,没有代码提示会很麻烦,是有解决办法的: 按下图打开 点击右上角的Add按钮,添加配置,配置如下,添加后点击OK: Location:http://mybatis.or ...
- 基于CefSharp开发浏览器(八)浏览器收藏夹栏
一.前言 上一篇文章 基于CefSharp开发(七)浏览器收藏夹菜单 简单实现了部分收藏夹功能 如(添加文件夹.添加收藏.删除.右键菜单部分功能) 后续代码中对MTreeViewItem进行了扩展,增 ...
- 剑指 Offer 29. 顺时针打印矩阵 + 蛇形矩阵 + 模拟 + 思维题
剑指 Offer 29. 顺时针打印矩阵 Offer_29 题目描述: 题解分析: 题目的初衷是将这道题当做一个简单题处理 这道题一开始想的太复杂了,其实可以参考迷宫广度优先搜索的过程,只不过在选定一 ...
- 前后端分离之DRF——1
1. 作用 1. 序列化,序列化器会把模型对象转成字典,经过 response 以后变成 json 字符串 2. 反序列化,把客户端发送过来的数据,经过 request 以后变成字典,序列化器可以把字 ...
- Nacos常用配置
属性配置 1. 配置年级是否显示 这里配置的屏蔽的年级,在运营后台去删掉相关id就行了 2. 过滤标签显示特定课程数据 指定 yaml 文件显示 course.tagCourse.tagName=寒假 ...
- subprocess如何设置命令超时时间
一.subprocess如何设置命令超时时间 最近遇到一个问题,就是我需要在服务器上执行某些shell命令,但是有些命令失败的时候是不会自动终止的,只会一直停在那里,很耗时间. 因此想到了设置超时时间 ...