PWA 那些事儿

一、背景

文章 2017 前端大事件和趋势回顾,2018 何去何从?中提到了 2017 年前端值得关注的十大事件,其中就提到了 PWA。

大家都知道 Native app 体验确实很好,下载到手机上之后入口也方便。它也有一些缺点:

开发成本高 (ios 和安卓)

软件上线需要审核

版本更新需要将新版本上传到不同的应用商店

想使用一个 app 就必须去下载才能使用,即使是偶尔需要使用一下下

而 web 网页开发成本低,网站更新时上传最新的资源到服务器即可,用手机带的浏览器打开就可以使用。但是出了体验上比 Native app 还是差一些,还有一些明显的缺点

手机桌面入口不够便捷,想要进入一个页面必须要记住它的 url 或者加入书签

没网络就没响应,不具备离线能力

不像 APP 一样能进行消息推送

那么什么是 PWA 呢?

二、What's PWA?

PWA 全称 Progressive Web App,即渐进式 WEB 应用。

一个 PWA 应用首先是一个网页, 可以通过 Web 技术编写出一个网页应用. 随后添加上 App Manifest 和 Service Worker 来实现 PWA 的安装和离线等功能 解决了哪些问题?

可以添加至主屏幕,点击主屏幕图标可以实现启动动画以及隐藏地址栏

实现离线缓存功能,即使用户手机没有网络,依然可以使用一些离线功能

实现了消息推送

它解决了上述提到的问题,这些特性将使得 Web 应用渐进式接近原生 App。

三、PWA 的实现

3.1 Manifest 实现添加至主屏幕

index.html

manifest.json

Manifest 参考文档:https://developer.mozilla.org/zh-CN/docs/Web/Manifest

可以打开网站 https://developers.google.cn/web/showcase/2015/chrome-dev-summit 查看添加至主屏幕的动图。

如果用的是安卓手机,可以下载 chrome 浏览器自己操作看看

3.2 service worker 实现离线缓存3.2.1 什么是 service worker

Service Worker 是 Chrome 团队提出和力推的一个 WEB API,用于给 web 应用提供高级的可持续的后台处理能力。

Service Workers 就像介于服务器和网页之间的拦截器,能够拦截进出的 HTTP 请求,从而完全控制你的网站。

最主要的特点

在页面中注册并安装成功后,运行于浏览器后台,不受页面刷新的影响,可以监听和截拦作用域范围内所有页面的 HTTP 请求。

网站必须使用 HTTPS。除了使用本地开发环境调试时 (如域名使用 localhost)

运行于浏览器后台,可以控制打开的作用域范围下所有的页面请求

单独的作用域范围,单独的运行环境和执行线程

不能操作页面 DOM。但可以通过事件机制来处理

事件驱动型服务线程

为什么要求网站必须是 HTTPS 的,大概是因为 service worker 权限太大能拦截所有页面的请求吧,如果 http 的网站安装 service worker 很容易被攻击

浏览器支持情况

浏览器支持情况详见: https://caniuse.com/#feat=serviceworkers

生命周期

当用户首次导航至 URL 时,服务器会返回响应的网页。

第 1 步: 当你调用 register() 函数时, Service Worker 开始下载。

第 2 步: 在注册过程中,浏览器会下载、解析并执行 Service Worker ()。如果在此步骤中出现任何错误,register() 返回的 promise 都会执行 reject 操作,并且 Service Worker 会被废弃。

第 3 步: 一旦 Service Worker 成功执行了,install 事件就会激活

第 4 步: 安装完成,Service Worker 便会激活,并控制在其范围内的一切。如果生命周期中的所有事件都成功了,Service Worker 便已准备就绪,随时可以使用了!

chrome://serviceworker-internals 来了解当前浏览器中所有已安装 Service Worker 的详细情况

3.2.2 HTTP 缓存与 service worker 缓存

HTTP 缓存

Web 服务器可以使用 Expires 首部来通知 Web 客户端,它可以使用资源的当前副本,直到指定的 “过期时间”。反过来,浏览器可以缓存此资源,并且只有在有效期满后才会再次检查新版本。 使用 HTTP 缓存意味着你要依赖服务器来告诉你何时缓存资源和何时过期。

service worker 缓存

Service Workers 的强大在于它们拦截 HTTP 请求的能力 进入任何传入的 HTTP 请求,并决定想要如何响应。在你的 Service Worker 中,可以编写逻辑来决定想要缓存的资源,以及需要满足什么条件和资源需要缓存多久。一切尽归你掌控!

3.2.3 实现离线缓存

index.html

注:Service Worker 的注册路径决定了其 scope 默认作用页面的范围。 如果 service-worker.js 是在 /sw/ 页面路径下,这使得该 Service Worker 默认只会收到 页面 / sw/ 路径下的 fetch 事件。 如果存放在网站的根路径下,则将会收到该网站的所有 fetch 事件。 如果希望改变它的作用域,可在第二个参数设置 scope 范围。示例中将其改为了根目录,即对整个站点生效。

service-worker.js

注:为什么用 request.clone() 和 response.clone() 需要这么做是因为 request 和 response 是一个流,它只能消耗一次。因为我们已经通过缓存消耗了一次,然后发起 HTTP 请求还要再消耗一次,所以我们需要在此时克隆请求 Clone the request—a request is a stream and can only be consumed once.

3.2.4 调试相关

chrome 浏览器打开 https://googlechrome.github.io/samples/service-worker/basic/index.html,这是一个实现了 service worker 离线缓存功能的网站,打开调试工具

介绍一个图中的 1. 和 2.

勾选可以模拟网站离线情况,勾选后 network 会有一个黄色警告图标,该网站已经离线。此时刷新页面,页面仍然能够正常显示

当前 service worker 的 scope。它能够拦截 https://googlechrome.github.i...,同样也能够拦截 https://googlechrome.github.i.../.html 下的请求

调试面板具体代表的什么参看 https://x5.tencent.com/tbs/guide/serviceworker.html 的第三部分

3.3 serice worker 实现消息推送

步骤一、提示用户并获得他们的订阅详细信息

步骤二、将这些详细信息保存在服务器上

步骤三、在需要时发送任何消息

不同浏览器需要用不同的推送消息服务器。以 Chrome 上使用 Google Cloud Messaging作为推送服务为例,第一步是注册 applicationServerKey(通过 GCM 注册获取),并在页面上进行订阅或发起订阅。每一个会话会有一个独立的端点(endpoint),订阅对象的属性 (PushSubscription.endpoint) 即为端点值。将端点发送给服务器后,服务器用这一值来发送消息给会话的激活的 Service Worker (通过 GCM 与浏览器客户端沟通)。

步骤一和步骤二index.html

步骤三 服务器发送消息给 service worker

app.js

service worker 监听 push 事件,将通知详情推送给用户

service-worker.js

扩展知识:service worker 的更新

总结

PWA 的优势

可以将 app 的快捷方式放置到桌面上,全屏运行,与原生 app 无异

能够在各种网络环境下使用,包括网络差和断网条件下,不会显示 undefind

推送消息的能力

其本质是一个网页,没有原生 app 的各种启动条件,快速响应用户指令

PWA 存在的问题

支持率不高: 现在 ios 手机端不支持 pwa,IE 也暂时不支持

Chrome 在中国桌面版占有率还是不错的,安卓移动端上的占有率却很低

各大厂商还未明确支持 pwa

依赖的 GCM 服务在国内无法使用

微信小程序的竞争

尽管有上述的一些缺点,PWA 技术仍然有很多可以使用的点。

service worker 技术实现离线缓存,可以将一些不经常更改的静态文件放到缓存中,提升用户体验。

service worker 实现消息推送,使用浏览器推送功能,吸引用户

渐进式开发,尽管一些浏览器暂时不支持,可以利用上述技术给使用支持浏览器的用户带来更好的体验。

原文:https://segmentfault.com/a/1190000012353473

本文来自企鹅号 - JavaScript媒体

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏ytkah

微信公众号后台编辑器出现短暂故障 附找回素材的方法

  今天下午(大致为8月15日13:30-14:40),微信公众平台后台编辑器出现短暂故障,保存素材后会出现被清空的现象,15:30左右已全面修复。   对于因...

2856
来自专栏腾讯移动品质中心TMQ的专栏

常用流量测试方法及一些思考

App性能测试中流量测试是其中重要的一项,网络场景(wifi、非wifi)、用户使用场景(页面加载流量、场景使用流量、待机流量),这些都是需要考虑的测试点。

4515
来自专栏散尽浮华

网站访问状态和超时时间监控报警设置

由于公司业务比较多,部署的站点也比较多。为了网站安全运行,以防故障发生时能第一时间知晓,特意编写下面监控脚本,对网站访问状态和超时时间进行监控:当code状态为...

3036
来自专栏我是攻城师

Jmeter压测快速体验

2623
来自专栏FreeBuf

Redis数据库安全手册

Redis是一个高性能的key-value数据库,这两年可谓火的不行。而Redis的流行也带来一系列安全问题,不少攻击者都通过Redis发起攻击。本文将讲解这方...

1836
来自专栏jeremy的技术点滴

试用openstack

5096
来自专栏我是攻城师

Nodejs笔记(一)

2827
来自专栏EAWorld

有状态容器实践:k8s集成ceph分布式存储

? 大家好,今天由我为大家介绍一下我们对于k8s与ceph集成的预研成果。对于k8s与ceph,我们也了解有限,有些理解不对的地方,还请大家指正。 ? 今天将...

5776
来自专栏FreeBuf

DNS Tunneling及相关实现

*本文原创作者:novsec,本文属FreeBuf原创奖励计划,未经许可禁止转载 ? DNS Tunneling,是隐蔽信道的一种,通过将其他协议封装在DNS协...

4097
来自专栏沃趣科技

Shell Limits设置问题导致用户不能登录

发生故障的环境为:RHEL 6.7,ORACLE 11gR2 RAC,其中集群节点1发生此故障,而节点2状态正常。

952

扫码关注云+社区