借助 workbox 将网站升级成 PWA

news/2024/4/27 18:43:55/文章来源:https://blog.csdn.net/weixin_34294649/article/details/88834503

PWA(Progressive Web Apps)是谷歌近几年一直在推进的 web 应用新模型。PWA 借助 Service Worker 缓存网站的静态资源,甚至是网络请求,使网站在离线时也能访问。并且我们能够为网站指定一个图标添加在手机桌面,实现点击桌面图标即可访问网站。

Web App Manifest

Web App Manifest 是一个 JSON 文件,它用来定义网站添加到桌面的图标以及从桌面图标进入网站时的一系列行为,如:启动样式,全屏主题等。

先创建 manifest.json

{"name": "blog-pwa","short_name": "blog-pwa","icons": [{"src": "https://segmentfault.com/img/icons/android-chrome-192x192.png","sizes": "192x192","type": "image/png"},{"src": "https://segmentfault.com/img/icons/android-chrome-512x512.png","sizes": "512x512","type": "image/png"}],"start_url": "/index.html","display": "standalone","background_color": "#000000","theme_color": "#4DBA87"
}

将文件引入:

<link rel=manifest href=/manifest.json>

我们可以从开发者工具上看我们的配置:

图片描述

icons 属性定义了添加到桌面的图标, display: standalone 表示我们要从桌面全屏启动,theme_color": "#4DBA87 是全屏启动时手机顶部状态栏的背景色,background_color": "#000000 是启动页的背景色,启动页目前不能定制,默认由 background_coloriconname 组合而成。

Web App Manifest很简单,只要照着文档每个属性看一遍就行。

Service Worker

Service Worker 是浏览器在后台独立于网页运行的脚本。是它让 PWA 拥有极快的访问速度和离线运行能力。

那它是如何做到的呢?我们一步步来看。

注册 Service Worker

if ('serviceWorker' in navigator) {navigator.serviceWorker.register('/service-worker.js').then(registration => {console.log('ServiceWorker registration successful with scope: ',registration.scope)}).catch(err => {console.log('ServiceWorker registration failed: ', err)})
}

需要注意的是,Service Worker 脚本除了域名为 localhost 时能运行在 http 协议下以外,只能运行 https 协议下。

安装

const CACHE_NAME = 'cache-v1'
const DATA_CACHE_NAME = 'data-cache-v1'const PRE_CACHE = ['/index.html', '/css/app.css', '/js/app.js']self.addEventListener('install', e => {console.log('[ServiceWorker] Install')e.waitUntil(caches.open(CACHE_NAME).then(cache => {return cache.addAll(PRE_CACHE)}))
})

在安装的时候预缓存网站的静态资源,任何资源路径出错都会造成 Service Worker 安装失败。

代理请求

self.addEventListener('fetch', e => {e.respondWith(caches.match(e.request).then(response => {if (response) {return response}const fetchRequest = e.request.clone()return fetch(fetchRequest).then(response => {// Check if we received a valid responseif (!response || response.status !== 200) {return response}const responseToCache = response.clone()caches.open(DATA_CACHE_NAME).then(cache => {cache.put(e.request, responseToCache)})return response})}))
})

安装成功后,Service Worker 就可以监听网站的所有请求,匹配到缓存时直接返回,未匹配到时请求服务器,服务器成功返回时添加到缓存。

更新

现在网站的 Service Worker 已经可以正常工作了,那如何更新它呢?

我们只需要修改 Service Worker 文件就可以更新它。当我们每次访问网站时都会去下载这个文件,当发现文件不一致时,就会安装这个新 Service Worker ,安装成功后,它将进入等待阶段。当我们关闭窗口重新导航到网站时(刷新网页不行),新 Service Worker 将开始控制网站。旧 Service Worker 终止工作并触发 activate 事件:

self.addEventListener('activate', e => {e.waitUntil(caches.keys().then(keyList => {return Promise.all(keyList.map(key => {if (key !== CACHE_NAME && key !== DATA_CACHE_NAME) {console.log('[ServiceWorker] Removing old cache', key)return caches.delete(key)}}))}))
})

在其卸载时一定要删除旧缓存,不然我们的网站永远无法更新。

上面只简单讲了 Service Worker 如何工作。我们会发现有很多问题需要我们进一步解决:

  1. 预缓存的静态资源修改后在下一次发版本时的文件名都不一样,手动写死太低效,最好每次都自动生成资源文件名。
  2. 缓存资源是以硬编码字符串判断是否有效,这样每次发版本都需要手动修改,才能更新缓存。并且每次都是全量更新。能否以文件的粒度进行资源缓存呢?
  3. 请求代理没有区分静态资源和动态接口。已经缓存的动态接口也会一直返回缓存,无法请求新数据。

上面只列出了三个明显的问题,还有很多问题是没有考虑到的。如果让我们自己来解决这些问题,不仅是工作量很大,而且也很难写出生产环境可用的 Service Worker

workbox

既然如此,我们最好是站在巨人的肩膀上,这个巨人就是谷歌。workbox 是由谷歌浏览器团队发布,用来协助创建 PWA 应用的 JavaScript 库。当然直接用 workbox 还是太复杂了,谷歌还很贴心的发布了一个 webpack 插件,能够自动生成 Service Worker 和 静态资源列表 - workbox-webpack-plugin。

只需简单一步就能生成生产环境可用的 Service Worker

const { GenerateSW } = require('workbox-webpack-plugin')new GenerateSW()

打包一下:

图片描述

还能说什么呢?谷歌大法好!当然这只是最简单的可用版本,其实这里有一个最严重的问题不知道有没人发现,那就是 importScripts 引用的是谷歌域名下的 cdn ,这让我们墙内的网站怎么用,所以我们需要把这个问题解决并自定义一些配置增强 Service Worker 的能力:

new GenerateSW({importWorkboxFrom: 'local',skipWaiting: true,clientsClaim: true,runtimeCaching: [{// To match cross-origin requests, use a RegExp that matches// the start of the origin:urlPattern: new RegExp('^https://api'),handler: 'staleWhileRevalidate',options: {// Configure which responses are considered cacheable.cacheableResponse: {statuses: [200]}}},{urlPattern: new RegExp('^https://cdn'),// Apply a network-first strategy.handler: 'networkFirst',options: {// Fall back to the cache after 2 seconds.networkTimeoutSeconds: 2,cacheableResponse: {statuses: [200]}}}]
})

首先 importWorkboxFrom 我们指定从本地引入,这样插件就会将 workbox 所有源文件下载到本地,墙内开发者的福音。上面提到过新 Service Worker 安装成功后需要进入等待阶段,skipWaiting: true 将使其跳过等待,安装成功后立即接管网站,注意这个要和 clientsClaim 一起设置为 trueruntimeCaching 顾名思义是配置运行时如何缓存请求的,这里只说一点,缓存跨域请求时 urlPattern 的值必须为 ^ 开头的正则表达式,其它的配置看文档都能得到详细的介绍。

再打包一次:

图片描述

现在我们就可以将打包好的代码部署到网站上了,源码在这,最后再上几张图:

图片描述

动图

参考

Web App Manifest

服务工作线程:简介

服务工作线程生命周期

workbox-webpack-plugin

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.luyixian.cn/news_show_755090.aspx

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Asp.net网站优化【转】

阅读目录 开始配置OutputCache启用内容过期解决资源文件升级问题启用压缩删除无用的HttpModule其它优化选项本文将介绍一些方法用于优化ASP.NET网站性能&#xff0c;这些方法都是不需要修改程序代码的。 它们主要分为二个方面&#xff1a; 1. 利用ASP.NET自身的扩展性进行优化。…

支付宝电脑网站支付

进入蚂蚁金服开放平台->开发者中心 按照文档新建应用&#xff0c;下载RSA密钥秘钥生成器&#xff0c;然后设置为应用公钥&#xff0c;设置完成后会自动生成支付宝公钥。 下载demo代码&#xff0c;下图为web支付&#xff0c;包括一系列功能及回调通知、异步通知。 更改Alipay…

阿里云系列——3.企业网站备案步骤---2018-1-4

网站部署之~阿里云系列汇总 http://www.cnblogs.com/dunitian/p/4958462.html 个人网站备案&#xff1a;http://www.cnblogs.com/dunitian/p/4958268.html 先说企业的域名实名认证&#xff1a;一张图就ok了 说下步骤&#xff0c;其实和个人差不多&#xff0c;简单过下吧 1.填写…

最新dedecms网页游戏开服表发号网站源码模板

模板介绍 最新dedecms网页游戏开服表发号网站源码模板&#xff0c;让你更精确的把握游戏开服时间和战略技巧。 这套网页游戏模板是织梦二次开发后的一套网页源码&#xff0c;后台也是经过二次开发后&#xff0c;适合游戏网站的一些参数说明及添加信息。 模板文件&#xff1a; 4…

如何设置受管的SEP客户端,禁止用户访问某些网站

请按以下步骤操作&#xff1a; 1. 登录 SEPM 控制台中&#xff0c;打开“防火墙策略”。 2. 在“防火墙策略”页面上&#xff0c;单击“规则”。 3. 在“规则”选项卡的“规则”列表下方&#xff0c;单击“添加规则”。 4. 在添加防火墙规则向导中&#xff0c;单击“下一步…

搭建网站必不可少的知识7

三次握手简单介绍一下 Syn握手信号&#xff0c;ACK是确认数据传输采用的TCP面向连接的可靠协议&#xff0c;正式传输数据前要先建立连接才行&#xff0c;当我们的访问页面的时候就要进行三次握手后才能获得数据&#xff0c;双向连接确认来保证数据的可靠传输。当电脑发出SYN包&…

网站

2019独角兽企业重金招聘Python工程师标准>>> www.findjar.com http://java-source.net/open-source/profilers/jrat memcached for Win32 http://jehiah.cz/projects/memcached-win32/ http://www.clocklink.com/ http://www.codechina.org/doc/google/gmapapi/…

Vue项目编译后部署在非网站根目录的解决方案

背景 同一个生产部署项目&#xff0c;基内外网的访问路径并不相同&#xff0c;内网是基于域名根目录来访问&#xff0c;而外网却指向了一个子目录。 eg. &#xff1a; vue-router: history模式内网环境&#xff1a;192.168.1.1:8080/index.html外网环境&#xff1a;domain.com/…

mouseover,mouseout,mouseenter,mouseleave的区别

相信做前端开发的都听说过“冒泡型事件”吧&#xff0c;《JavaScript高级程序设计》第九章有详细的讲述&#xff0c;但是&#xff0c;在学习的时候一知半解&#xff0c;也没详细去理解&#xff0c;导致最近在工作中碰到了问题&#xff1a;有许多 li 标签&#xff0c;标签上有2个…

吉林社科规划网站转换计划

概述<?xml:namespace prefix o ns "urn:schemas-microsoft-com:office:office" />吉林社科网站:http://www.jlpopss.gov.cn是本人开发&#xff08;后台代码&#xff0c;非界面设计&#xff09;并长时间维护的网站&#xff0c;根据以前开发的经验决定对系统进…

团队项目(MVP-----------新能源汽车无线充电管理网站)个人任务(6)

本周任务&#xff1a;该周是项目完善的最后一周&#xff0c;本周主要的任务是继续优化界面&#xff0c;注意一些细节上的处理。 Github地址&#xff1a;https:/github.com/xiangbaobaojojo/car转载于:https://www.cnblogs.com/Ci0Yu/p/8079105.html

如何把canvas元素作为网站背景总结详解

如何把canvas元素作为网站背景总结详解 一、总结 一句话总结&#xff1a;最简单的做法是绝对定位并且z-index属性设置为负数。 1、如何把canvas元素作为网站背景的两种方法&#xff1f; a、设置层级&#xff08;本例代码就是用的这种方法&#xff09;&#xff1a; position:abs…

昆明网站建设公司排名榜

我作为昆明地区的一个网站开发人员&#xff0c;在昆明已经有3年的网站开发经验了&#xff0c;对于昆明网站建设公司或多或少的都有所了解&#xff0c;或是自己接触&#xff0c;或是听朋友介绍&#xff0c;或是同事的经验&#xff0c;在加上自己的面试过的公司&#xff0c;对昆明…

linux实战考试题:统计一个网站每小时的PV数量-看看你会么?

老男孩教育第三关课后实战考试题练习&#xff1a;请统计老男孩老师的博客 http://oldboy.blog.51cto.com/ 博客每小时所有用户访问的pv数量&#xff08;统计样本5个小时以上&#xff09;。 要求&#xff1a;老男孩20-21期的学生必答题&#xff08;务必自己搞出来&#xff0c;能…

360浏览器插件开发_360浏览器中SEO优化插件如何安装

今天网校同学陈总来到我公司做客&#xff0c;双方交流下2019年各自企业运营发展战略方向&#xff0c;谈到关于网站优化方面的知识&#xff0c;他查看了下我们曾经做过的危险品货代公司网站的排名&#xff0c;他看到我电脑的浏览器上有SEO插件&#xff0c;查看优化信息非常方便&…

常见网络工程师面试题:电脑是如何访问网站的?

咱们网络工程师去面试的时候&#xff0c;经常会有面试官问到&#xff1a;请尽可能详细的介绍&#xff0c;一台pc从开机&#xff0c;到打开csdn主页的过程&#xff01; 那什么样的回答才能让面试官满意呢&#xff1f; 大家可以看看下面的参考回答~ &#xff08;1&#xff09; 首…

网工面试题:主机访问网站的数据流分析是什么样的?有哪些注意事项?

哈喽&#xff0c;大家好&#xff0c;我是网工学姐~ 今天给大家整理了一些面试技巧&#xff0c;大家要是觉得好可以点赞收藏哦&#xff01; 访问面试中常见的一些面试题&#xff1a;主机访问网站的数据流分析是什么样的&#xff1f; 参考答案&#xff1a; 1、打开主机&#xff0…

网站建设:简单动态网站搭建

2019独角兽企业重金招聘Python工程师标准>>> 通过前面Clouder课程的学习&#xff0c;或许你已经掌握了在云服务器上发布和部署静态网页的方法&#xff0c;那么如何搭建一个可以随时更新内容的动态网站&#xff1f;通过本课程的学习&#xff0c;你将掌握如何在云端搭…

PayPal网站付款标准版(for PHP)

原文:PayPal网站付款标准版(for PHP)简单整理一下PHP项目整合PayPal支付功能。 一、表单的构建&#xff1a; <form method"post" name"form" action"https://www.paypal.com/cgi-bin/webscr"> <input type"hidden" name"…

Yahoo!网站性能最佳体验的34条黄金守则之内容篇

2019独角兽企业重金招聘Python工程师标准>>> Yahoo!的Exceptional Performance团队为改善Web性能带来最佳实践。他们为此进行了一系列的实验、开发了各种工具、写了大量的文章和博客并在各种会议上参与探讨。最佳实践的核心就是旨在提高网站性能。 Excetional Perfo…