天人合一物我相融,站点升级Web应用PWA(ProgressiveWebApps)实践
PWA(Progressive web apps,渐进式 Web 应用)使用现代的 Web API 以及传统的渐进式增强策略来创建跨平台 Web 应用程序,说白了,PWA可以让我们的站点以原生APP的形式运行,但相比于安装原生APP应用,访问PWA显然更加容易和迅速,还可以通过链接来分享PWA应用。
有许多知名的网络平台已经将 PWA 方案落地,比如Twitter。选择增强的网站体验而不是原生应用。事实上使用PWA也确实从中获得了显而易见的益处。https://www.pwastats.com 这个网站上分享了许多案例研究,PWA相比于传统应用有以下好处:
1、减少应用安装后的加载时间,通过 Service Workers 来进行缓存,以此来节省带宽和时间。
2、当应用有可用的更新时,可以只更新发生改变的那部分内容。相比之下,对于一个原生应用而言,即便是最微小的改动也需要强制用户去进行热更新或者再次下载整个应用。
3、外观和使用感受与原生平台更加融为一体——应用图标被放置在主屏幕上,应用可以全屏运行等。
凭借系统通知和推送消息与用户保持连接,对用户产生更多的吸引力,并且提高转换效率。
诚然,从零开始研发PWA应用会有一定的成本,但如果我们本身就拥有基于Web的站点,那么就可以通过增加对应的配置文件和服务进行升级操作,直接拥有PWA应用。 HTTPS服务
首先PWA要求站点的请求方式为HTTPS,如果是生产环境,可以通过为Nginx服务器配置SSL的方式进行适配,但是线下环境测试PWA时就有点费劲了,所以通过openssl工具为本地域名localhost做自签证书: openssl req -x509 -out localhost.crt -keyout localhost.key -newkey rsa:2048 -nodes -sha256 -days 3650 -subj "/CN=localhost" -extensions EXT -config <( printf "[dn] CN=localhost [req] distinguished_name = dn [EXT] subjectAltName=DNS:localhost keyUsage=digitalSignature extendedKeyUsage=serverAuth")
产出:localhost.crt和localhost.key文件,key是私用密钥openssl格式,通常是rsa算法。csr是证书请求文件,用于申请证书,在制作csr文件的时,必须使用自己的私钥来签署申,还可以设定一个密钥。
将文件放到项目的根目录下,随后在构建项目服务的时候配置即可,以Tornado为例: server = httpserver.HTTPServer(app,xheaders=True,ssl_options={ "certfile": "./localhost.crt", "keyfile": "./localhost.key", }) # 指定端口 server.listen(443)
这里通过设置ssl_options参数来导入私钥和证书,同时将端口改为HTTPS默认端口号443。如此,在本地也可以对PWA进行测试了,当然了,如果不需要本地操作,也可以跳过这步。 manifest.json配置文件
为了实现 PWA 应用添加至桌面的功能,除了要求站点支持 HTTPS 之外,还需要准备 manifest.json 文件去配置应用的图标、名称等信息。
以本站为例,在站点根目录创建manifest.json文件: { "name": "刘悦的技术博客", "short_name": "刘悦的技术博客", "description": "刘悦的技术博客", "icons": [ { "src": "https://v3u.cn/v3u/Public/images/pwa192.png", "sizes": "192x192", "type": "image/png" }, { "src": "https://v3u.cn/v3u/Public/images/pwa512.png", "sizes": "512x512", "type": "image/png" } ], "background_color": "#FFF", "theme_color": "#FFF", "display": "standalone", "orientation": "portrait", "start_url": "/", "scope": "/" }
由上至下,依次是 PWA 应用的名称、描述、图标文件、banner颜色、显示方式、开始页面的链接和 PWA 的作用域。为此我们需要提供两张不同分辨率的站点图标文件:
ServiceWorker服务
Service Worker是一个注册在指定源和路径下的事件驱动型Web Worker。它充当了Web应用程序与浏览器之间的代理服务器,进行资源在文件级别下的缓存与操控,拦截页面请求,实现在不同的情况下对不同请求的响应策略。
Service Worker本质上就是一个Web Worker,因此它具有Web Worker的特点:无法操作DOM、脱离主线程、独立上下文。
Service Worker还具有这些特点:只能在Https下使用、运行在浏览器后台,不受页面刷新影响、更强大的离线缓存能力(使用Cache API)、请求拦截能力、完全异步,不能使用同步API、持续运行,第一次访问页面后,Service Worker就会安装激活并持续运行,直到手动销毁。
以本站为例,在站点根目录创建sw.js文件,注意Service Worker文件位置一定得在根目录,如果不在根目录也要通过重写或者url映射让其可以通过根目录路径进行访问,如:https://v3u.cn/sw.js,否则浏览器会检测不到Service Worker服务: var CACHE_NAME = "v3u-cache-v1"; var urlsToCache = [ "/", "/v3u/Public/css/tidy_min.css" ]; self.addEventListener("install", function (event) { event.waitUntil( caches.open(CACHE_NAME).then(function (cache) { console.log("Open cache"); return cache.addAll(urlsToCache); }).then(function () { self.skipWaiting(); }) ); });
当我们为页面注册Service Worker后,Service Worker开始进行安装,安装成功之后,会在worker中触发install事件;如果安装失败,则进入废弃状态。
如果Service Worker逻辑文件更新(相关资源文件变动或者内部逻辑更新等),Service Worker会重新安装,如果这个时候,页面依然存在激活状态下的worker(旧的Service Worker),那么新的worker会进入waiting状态进行等待,直到我们主动去操作worker强制其更新,或者等待用户关闭所有页面,这个时候新的worker才会进入到激活状态。
在install事件中,我们使用caches.open方法打开cache对象,并通过cache.addAll缓存所有我们列出的文件。如果Service Worker存在更新,我们使用skipWaiting跳过等待,直接强制新的worker进入激活状态。
随后,添加fetch事件: self.addEventListener("fetch", function(event){ if(event.request.method !== "GET") return; event.respondWith( caches.match(event.request).then(function(response){ if(response){ console.log("return caches"); return response; }else{ return fetch(event.request).catch(function(){ if(/.html$/.test(event.request.url)) return caches.match("/html/neterror.html"); }); } }) ) });
这里只监听了全站的GET请求方式,即我们只希望控制资源请求。通过caches.match检查请求是否命中了缓存,如果命中,则直接返回缓存给用户,防止重复请求,节约资源。如果没有命中,则将使用fetch方法请求网络资源并返回给用户。当网络状态异常时(fetch().catch()),返回404页面的缓存给用户,告知用户当前处于无网络状态,不能访问相关页面。指定了一些页面和文件进行缓存,我们希望用户在无网络的情况下只能访问到我们指定缓存的页面。
当然,还有另外一种情况,我们指定了一些页面进行缓存(常用页面),当用户访问到一些不常用页面时,再对其进行缓存。这样,我们可以对资源配置进行优化,不过多的占用用户本地资源去缓存所有页面,因为PWA的缓冲本身是存储到客户端的,对于非所有用户的常用页面,按需缓存: self.addEventListener("fetch", function(event){ if(event.request.method !== "GET") return; event.respondWith( caches.match(event.request).then(function(response){ if(response){ console.log("return caches"); return response; }else{ return fetch(event.request).then(function(res){ var responseToCache = res.clone(); caches.open(CACHE_NAME).then(function(cache){ catch.put(event.request, responseToCache); }) return res; }); } }) ) });
至此,ServiceWorker服务文件就撰写完成了。 生产环境上线配置:
分别将manifest.json和sw.js文件分别上传到生产环境之后,在页面的head标签中进行声明:
声明后,注意访问一下是否正确返回:https://v3u.cn/manifest.json
随后在页面中注册Service Worker服务:
这里首先判断当前浏览器的navigator是否支持serviceWorker,随后使用navigator.serviceWorker.register函数来注册Service Worker。其中,参数为要执行的worker逻辑文件路径,注意这个路径是基于origin的,而非当前文件。
接着键入组合键,打开chrome浏览器的开发者工具:
Mac系统上的"⌥+⌘+I"
Win系统上的"F12+Ctrl+Shift+I"
在Chrome 的应用标签下进行检查,看应用清单有没有读出你的 PWA 应用信息配置文件:
随后在serviceWorker标签下检查serviceWorker是否正确运行:
接着访问站点,在地址栏即可添加PWA应用:
访问效果:
结语
渐进式增强和响应式设计已经可以让我们构建对移动端非常友好的站点,而PWA则又在我们的身后轻轻地推了一把,黄河之水源可滥觞,星星之火正在燎原,一年以内,我们都将感到PWA的灼人温度。
泰康人寿首笔个人养老金业务落地中证网讯(记者薛瑾)11月25日,泰康人寿首笔个人养老金业务落地,在北京完成资金帐户开立和缴存全流程操作。日前,中国银保信披露首批个人养老金保险产品名单,泰康人寿成为6家入选公司中
杨钰莹把自己打扮成贵妇,穿皮草拎奢牌包真高调,51岁嫩得更似35说到娱乐圈的不老女神,就不得不提杨钰莹,如今都年过半百了,她的面部轮廓却没什么变化,皮肤依旧紧致饱满,骨子里的甜美与灵气丝毫不减,说她三十出头也毫无违和感。昔日难得高调把自己打扮成
云淡风轻我想对你说云很淡,风很轻,任星辰浮浮沉沉这就是风轻云淡的生活。生活本平淡,但能将平淡的生活过得精致而多彩,身忙而不疲,心忙而不乱。闲暇时,三五好友,赏景品茶,听花开花落,看云卷云舒
人,不知恩不可帮人,不明理不可交这个世上,最美好的事情,不是自己多富有,而是能多替他人着想,力所能及地帮助他人不是自己心思有多精,而是能明白事理为人坦诚,交到几个知心的朋友。帮助一次他人,会得到一份快乐交到一个好
白银有色集团股份有限公司2022年劳动用工招聘公告白银有色集团股份有限公司(以下简称白银集团)成立于1954年,是新中国一五时期156个重点建设项目之一,目前注册资本74。05亿元,分子公司43家,在册职工1。4万余人,业务涵盖铜
失眠最怕这个菜,好吃又便宜,补血助眠,一觉安睡到天亮导语失眠最怕这菜,好吃又便宜,2元做一大盘,补血助眠,安睡到天亮。大家好我是傻姐美食,生活中唯有美食和美景不可辜负。由于最近一段时间比较忙,好久没有和闺蜜一起聊天吃饭了,今天打电话
真情融入,是讲好思政课的触点陈文奡近日,天津一高校教师在讲到中国近代史时感触落泪,引发台下学生共鸣,登上微博热搜。前一阵儿,郑州大学周荣方老师也因讲述近代史时数度哽咽而意外走红。频频出圈的高校思政老师,讲课的
24岁硕士为看梅西辞大厂工作带3500欧徒步去卡塔尔睡在清真寺摘要为了见证偶像梅西在世界杯上的最后一舞,24岁的北京男孩Shrek带着3500欧元,踏上了一条足球朝圣之路历时三个月,徒步和骑行穿越中亚中东十国,最终在11月19日抵达卡塔尔。梦
今年捐赠149亿元,刘强东打响了共同富裕的第一枪近期刘强东给兄弟们的一封信又火了,信的内容主要是高管降薪,给德邦的一线员工交纳五险一金以及回报股东。京东物流是今年7月完成收购德邦,这同工同酬还是来得很快,从给京东物流的员工缴纳社
论文推介固体地球科学(Geoscience)还有什么有待发现?陈凤婷编者按固体地球科学还有重要科学问题没有解决吗?如果有,是什么?最近,美国犹他州大学能源与固体地球科学所地质与地球物理系RasoulSorkhabi博士在国际地科联刊物Epis
日子漫长,感谢遇见以前遇到难事,我总会祈求上帝告诉我这一生最痛苦的时刻,这样的话,在遇到的困难时,就能有心理准备,当然这是不可能的。经历过选调生上岸失败后我便没有这种奢望了,因为痛越想结束就越痛,我