PWA介绍及快速上手搭建一个PWA应用的方法


Posted in Javascript onJanuary 27, 2019

PWA初次体验

前言:本示例不用安装任何东西

部分资源来自网络资源及PWA官网,不要把PWA想象的太复杂,跟着示例走一下,你行的。

PWA介绍

一个新的前端技术,PWA( 全称:Progressive Web App )也就是说这是个渐进式的网页应用程序。

官网: https://developers.google.com/web/progressive-web-apps/

是 Google 在 2015 年提出,2016年6月才推广的项目。是结合了一系列现代Web技术的组合,在网页应用中实现和原生应用相近的用户体验。

官网上给出 PWA 的宣传是 : Reliable ( 可靠的 )、 Fast ( 快速的 )、 Engaging ( 可参与的 )

Reliable:当用户从手机主屏幕启动时,不用考虑网络的状态是如何,都可以立刻加载出 PWA。

Fast:这一点应该都很熟悉了吧,站在用户的角度来考虑,如果一个网页加载速度有点长的话,那么我们会放弃浏览该网站,所以 PWA 在这一点上做的很好,他的加载速度是很快的。

Engaging: PWA 可以添加在用户的主屏幕上,不用从应用商店进行下载,他们通过网络应用程序 Manifest file 提供类似于 APP 的使用体验( 在 Android 上可以设置全屏显示哦,由于 Safari 支持度的问题,所以在 IOS 上并不可以 ),并且还能进行 ”推送通知” 。

PWA关键技术

  • Service Worker (可以理解为服务工厂)
  • Manifest (应用清单)
  • Push Notification (推送通知)

Service Worker

以下用SW来表示

SW 是什么呢?这个是离线缓存文件。我们 PWA 技术使用的就是它!SW 是浏览器在后台独立于网页运行的脚本,它打开了通向不需要网页或用户交互的功能的大门,因为使用了它,才会有的那个 Reliable 特性吧,SW 作用于 浏览器于服务器之间,相当于一个代理服务器。

浏览器支持

顺便带一句:目前只能在 HTTPS 环境下才能使用SW,因为SW 的权利比较大,能够直接截取和返回用户的请求,所以要考虑一下安全性问题。

PWA介绍及快速上手搭建一个PWA应用的方法

事件机制

PWA介绍及快速上手搭建一个PWA应用的方法

功能(还是比较逆天的)

  • 后台数据的同步
  • 从其他域获取资源请求
  • 接受计算密集型数据的更新,多页面共享该数据
  • 客户端编译与依赖管理
  • 后端服务的hook机制
  • 根据URL模式,自定义模板
  • 性能优化
  • 消息推送
  • 定时默认更新
  • 地理围栏

生命周期

PWA介绍及快速上手搭建一个PWA应用的方法

Parsed ( 解析成功 ): 首次注册 SW 时,浏览器解决脚本并获得入口点,如果解析成功,就可以访问到 SW 注册对象,在这一点中我们需要在 HTML 页面中添加一个判断,判断该浏览器是否支持 SW 。

Installing ( 正在安装 ):SW 脚本解析完成之后,浏览器会尝试进行安装,installing 中 install 事件被执行,如果其中有 event.waitUntil ( ) 方法,则 installing 事件会一直等到该方法中的 Promise 完成之后才会成功,如果 Promise 被拒绝,则安装失败,SW会进入 Redundant( 废弃 )状态。

Installed / Waiting (安装成功/等待中):如果安装成功,SW 将会进入这个状态。

Activating ( 正在激活 ):处于 waiting 状态的 SW 发生以下情况,将会进入 activating 状态中:

当前已无激活状态的 worker 、 SW脚本中的 self.skipWaiting()方法被调用 ( ps: self 是 SW 中作用于全局的对象,这个方法根据英文翻译过来也能明白什么意思啦,跳过等待状态 )、用户已关闭 SW 作用域下的所有页面,从而释放了当前处于激活状态的 worker、超出指定时间,从而释放当前处于激活状态的 worker

Activated ( 激活成功 ):该状态,其成功接收了 document 全面控制的激活态 worker 。

Redundant ( 废弃 ):这个状态的出现时有原因的,如果 installing 事件失败或者 activating 事件失败或者新的 SW 替换其成为激活态 worker 。installing 事件失败和 activating 事件失败的信息我们可以在 Chrome 浏览器的 DevTools 中查看

Manifest

Web App Manifest 是一个 W3C 规范,它定义了一个基于 JSON 的 List 。Manifest 在 PWA 中的作用有:

​ 能够将你浏览的网页添加到你的手机屏幕上

​ 在 Android 上能够全屏启动,不显示地址栏 ( 由于 Iphone 手机的浏览器是 Safari ,所以不支持哦)

​ 控制屏幕 横屏 / 竖屏 展示

​ 定义启动画面

​ 可以设置你的应用启动是从主屏幕启动还是从 URL 启动

​ 可以设置你添加屏幕上的应用程序图标、名字、图标大小

Push Notification

Push 和 Notification 是两个不同的功能,涉及到两个 API 。

​ Notification 是浏览器发出的通知消息。

​ Push 和 Notification 的关系,Push:服务器端将更新的信息传递给 SW ,Notification: SW 将更新的信息推送给用户。

PWA示例

准备

我们先创建一个关于 PWA 的项目文件夹,

进入文件夹下我们准备一张 120x120的图片一张,作为我们的应用程序图标。

创建一个 index.html 文件

创建一个 main.css 文件

创建一个 manifest.json 文件

创建一个 sw.js 文件

PWA介绍及快速上手搭建一个PWA应用的方法

index.html

<!DOCTYPE html>
<html lang="en">
<head>
 <meta charset="UTF-8">
 <title>Hello PWA</title>
 <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
 <link rel="stylesheet" href="main.css" rel="external nofollow" >
 <link rel="manifest" href="manifest.json" rel="external nofollow" >
</head>
<body>
 <h3>Hello PWA</h3>
</body>
<script>
 // 检测浏览器是否支持SW
 if(navigator.serviceWorker != null){
 navigator.serviceWorker.register('sw.js')
 .then(function(registartion){
  console.log('支持sw:',registartion.scope)
 })
 }
</script>
</html>

main.css

h3{
 color: #f00;
}

manifest.json

short_name: “ " 用户主屏幕上的应用名字

display : “standalone" 设置启动样式,让您的网络应用隐藏浏览器的 URL 地址栏

start_url : “/“ 设置启动网址,如果不提供的话,默认是使用当前页面

theme_color : “ “ 用来告知浏览器用什么颜色来为地址栏等 UI 元素着色

background_color: “ ” 设置启动页面的背景颜色

icons:”” 就是添加到主屏幕之后的图标

{
 "name": "一个PWA示例",
 "short_name": "PWA示例",
 "start_url": "/index.html",
 "display": "standalone",
 "background_color": "#fff",
 "theme_color": "#3eaf7c",
 "icons": [
 {
  "src": "/youhun.jpg",
  "sizes": "120x120",
  "type": "image/png"
 }
 ],
}

sw.js

看网上很多人都安装的hs和ngrokk去调试,在这里为了照顾新手我是直接引用的sw

处理静态缓存,首先定义需要缓存的路径,以及需要缓存的静态文件的列表。

借助 SW 注册完成安装 SW 时,抓取资源写入缓存中。使用了一个方法那就是 self.skipWaiting( ) ,为了在页面更新的过程当中,新的 SW 脚本能够立刻激活和生效。

importScripts("https://storage.googleapis.com/workbox-cdn/releases/3.1.0/workbox-sw.js");
var cacheStorageKey = 'minimal-pwa-1'
var cacheList=[
 '/',
 'index.html',
 'main.css',
 'youhun.jpg'
]
self.addEventListener('install',e =>{
 e.waitUntil(
 caches.open(cacheStorageKey)
 .then(cache => cache.addAll(cacheList))
 .then(() => self.skipWaiting())
 )
})

处理动态缓存,我们监听 fetch 事件,在 caches 中去 match 事件的 request ,如果 response 不为空的话就返回 response ,最后返回 fetch 请求,在 fetch 事件中我们可以手动生成 response 返回给页面。

更新静态资源,缓存的资源会跟随着版本的更新会过期的,所以会根据缓存的字符串名称清除旧缓存。在新安装的 SW 中通过调用 self.clients.claim( ) 取得页面的控制权,这样之后打开页面都会使用版本更新的缓存。旧的 SW 脚本不在控制着页面之后会被停止,也就是会进入 Redundant 期。

self.addEventListener('fetch',function(e){
 e.respondWith(
 caches.match(e.request).then(function(response){
  if(response != null){
  return response
  }
  return fetch(e.request.url)
 })
 )
})
self.addEventListener('activate',function(e){
 e.waitUntil(
 //获取所有cache名称
 caches.keys().then(cacheNames => {
  return Promise.all(
  // 获取所有不同于当前版本名称cache下的内容
  cacheNames.filter(cacheNames => {
   return cacheNames !== cacheStorageKey
  }).map(cacheNames => {
   return caches.delete(cacheNames)
  })
  )
 }).then(() => {
  return self.clients.claim()
 })
 )
})

部署

我们可以把当前pwa目录的所有内容都扔进服务器中,或者coding Pages和gitHub Pages也是可以的,当然,记得开启https。在上变介绍过SW的权利比较大,为了安全性,我们使用https协议来访问。

试着访问一下,我们这里用的coding Pages并且绑定了自己的域名

打开 chrom 的调试工具,打开 application ,点击 service workers 之后我们会发现 sw.js 脚本已经存到了 SW 中 。

PWA介绍及快速上手搭建一个PWA应用的方法

我们打开 Network 刷新页面一下,看看,我们的页面资源来自 SW 而不是其他的地方,在 Console 中也打印出了我们在 index.html 中判断的语句,浏览器支持就会打印出这一句话。

PWA介绍及快速上手搭建一个PWA应用的方法

接下来我们断网操作,在 Application 中给 Offline 打上对勾就行啦。然后刷新页面,我们仍然能看到之前的页面,原因就是我们在上图看到,他的资源是从 SW 上获得到的。当我们第一次打开这个页面的时候,Resopnse 对象被存到了 Cache Storage ( 定义在 SW 规范中 ,相关资料请同学们自行查询啦 )中,我们看下图:

PWA介绍及快速上手搭建一个PWA应用的方法

通过存放到 Cache Storage 中,我们下次访问的时候如果是弱网或者断网的情况下,就可以不走网络请求,而直接就能将本地缓存的内容展示给用户,优化用户的弱网及断网体验。

这个时候肯定会有同学在想,如果内容更新了,那么页面展示的内容是新内容呢还是旧内容呢?下面我们操作一下,打开 index.html 文件,我们在 body 中添加一个 p 标签 ,然后回到页面刷新。

PWA介绍及快速上手搭建一个PWA应用的方法

PWA介绍及快速上手搭建一个PWA应用的方法

我们看到,页面上的内容并没有显示出我刚刚添加的那个 p 标签。这说明了,我们拿到的数据还是从 Cache Storage 中获取到的,Cache Storage中的内容并没有更新,强制刷新也不行哦,那么我们怎么才能让我刚刚添加的那个 p 标签显示出来呢。

我们打开 sw.js 脚本文件,我们修改一下 cacheStorageKey。

PWA介绍及快速上手搭建一个PWA应用的方法

修改后,我们再次打开该网址,强制刷新下或者关掉浏览器重新打开。

页面中出现了刚刚添加的P标签,我们再看一下 Cache Storage 中的缓存名字,已经被修改。

PWA介绍及快速上手搭建一个PWA应用的方法 总结

如果是使用coding或者gitHub提供的pages服务,则需要注意最好绑定下独立域名。如果不绑定则注意下文件请求路径即可。

研究PWA门槛不低,部署的服务器要求HTTPS,ServiceWorker涉及API众多,需要单独学习,另外npm中也已经有这个包了https://www.npmjs.com/package/web-pwa ,玩玩可以,真正部署到项目生产环境可能坑很多,但有坑填坑,不折腾还叫前端么。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
javascript移出节点removeChild()使用介绍
Apr 03 Javascript
jquery制作漂亮的弹出层提示消息特效
Dec 23 Javascript
详谈javascript中的cookie
Jun 03 Javascript
javascript中JSON对象与JSON字符串相互转换实例
Jul 11 Javascript
移动前端图片压缩上传的实例
Dec 06 Javascript
React中嵌套组件与被嵌套组件的通信过程
Jul 11 Javascript
webpack项目使用eslint建立代码规范实现
May 16 Javascript
vue 父组件中调用子组件函数的方法
Jun 06 Javascript
Promise扫盲贴
Jun 24 Javascript
详解Vue2.5+迁移至Typescript指南
Aug 01 Javascript
JS Ajax请求会话过期处理问题解决方法分析
Nov 16 Javascript
vue data变量相互赋值后被实时同步的解决步骤
Aug 05 Javascript
原生JS检测CSS3动画是否结束的方法详解
Jan 27 #Javascript
原生JS实现的跳一跳小游戏完整实例
Jan 27 #Javascript
nuxt中使用路由守卫的方法步骤
Jan 27 #Javascript
vue-cli构建vue项目的步骤详解
Jan 27 #Javascript
vue实现的仿淘宝购物车功能详解
Jan 27 #Javascript
详解vue路由篇(动态路由、路由嵌套)
Jan 27 #Javascript
实例讲解JS中pop使用方法
Jan 27 #Javascript
You might like
PHP5.3的垃圾回收机制(动态存储分配方案)深入理解
2012/12/10 PHP
PHP小技巧之JS和CSS优化工具Minify的使用方法
2014/05/19 PHP
windwos下使用php连接oracle数据库的过程分享
2014/05/26 PHP
thinkphp查询,3.X 5.0方法(亲试可行)
2017/06/17 PHP
ThinkPHP框架表单验证操作方法
2017/07/19 PHP
使用vs code编辑调试php配置的方法
2019/01/29 PHP
JQuery 网站换肤功能实现代码
2009/11/02 Javascript
理解Javascript_01_理解内存分配原理分析
2010/10/11 Javascript
10个基于Jquery的幻灯片插件教程
2010/10/29 Javascript
jQuery在vs2008及js文件中的无智能提示的解决方法
2010/12/30 Javascript
JQuery自适应IFrame高度(支持嵌套 兼容IE,ff,safafi,chrome)
2011/03/28 Javascript
代码触发js事件(click、change)示例应用
2013/12/13 Javascript
js点击选择文本的方法
2015/02/09 Javascript
js基于面向对象实现网页TAB选项卡菜单效果代码
2015/09/09 Javascript
令按钮悬浮在(手机)页面底部的实现方法
2017/05/02 Javascript
Vuex 单状态库与多模块状态库详解
2018/12/11 Javascript
vue-router启用history模式下的开发及非根目录部署方法
2018/12/23 Javascript
javascript获取select值的方法完整实例
2019/06/20 Javascript
在Vue环境下利用worker运行interval计时器的步骤
2019/08/01 Javascript
js实现指定时间倒计时效果
2019/08/26 Javascript
基于Vue+ElementUI的省市区地址选择通用组件
2019/11/20 Javascript
[46:43]DOTA2上海特级锦标赛主赛事日 - 1 胜者组第一轮#2LGD VS MVP.Phx第二局
2016/03/02 DOTA
浅析Python装饰器以及装饰器模式
2018/05/28 Python
python中eval与int的区别浅析
2019/08/11 Python
python实现机器人卡牌
2019/10/06 Python
StudentUniverse英国:学生航班、酒店和旅游
2019/08/25 全球购物
ajax是什么及其工作原理
2012/02/08 面试题
如何执行一个shell程序
2012/11/23 面试题
校园摄影活动策划方案
2014/02/05 职场文书
党员教师学习党的群众路线教育实践活动心得体会
2014/10/31 职场文书
医院办公室主任岗位职责
2015/04/01 职场文书
毕业生爱心捐书倡议书
2015/04/27 职场文书
新员工入职感想
2015/08/07 职场文书
golang import自定义包方式
2021/04/29 Golang
对PyTorch中inplace字段的全面理解
2021/05/22 Python
JS精髓原型链继承及构造函数继承问题纠正
2022/06/16 Javascript