什么是PWA(渐进式 Web 应用)
PWA(Progressive Web Apps,渐进式 Web 应用)运用现代的 Web API 以及传统的渐进式增强策略来创建跨平台 Web 应用程序。这些应用无处不在、功能丰富,使其具有与原生应用相同的用户体验优势。PWA 是可被发现、易安装、可链接、独立于网络、渐进式、可重用、响应性和安全的。
简单理解,PWA可以将Web应用转化成能够在多平台设备上使用的原生应用程序并且具有和原生应用接近的交互体验,无需下载直接安装。
注意:PWA并不是一种单独的技术,而是多项Web技术集成的Web App,其核心技术包括App Manifest、Service Worker、Web Push等。
pwa优势
它比原生应用更轻量,但是却比现有的 Web APP 的功能更加丰富。最大也是最关键的区别是它能够脱离浏览器的「束缚」(虽然依然是基于浏览器的技术),能够把 PWA 网站添加到你的桌面上,不管是 PC 操作系统还是手机操作系统,类似于一个原生应用一样,并且拥有媲美原生应用的体验。而微信支付宝等小程序更封闭,是 Web 的子集。
快速为网站配置PWA
- 开启HTTPS,并且强制HTTPS
- 根目录上传 Manifest.JSON 并修改内容
- 根目录上传 Service-Worker.JS
- 注册Service Worker
配置Manifest
Manifest是一份用JSON记录网站信息的清单,其中包含了应用的标题、图标的大小与路径、加载页的背景颜色等,只有编写了这份清单浏览器才能正确处理Web App信息。在编写Manifest时会发现有不同拓展名,如manifest.webapp、manifest.json以下是我编写的一份Manifest示例:
{
"background_color": "#fff", //Web App启动时的背景颜色,可以使用预设的一些颜色名字如red,blue等,或者直接使用HEX颜色值如#66ccff(天依蓝)
"description": "Describe your site.", //Web App的描述,这里的内容将会在安装时展现
"display": "fullscreen", //Web App展示的方式,可选的值有fullscreen,standalone,minimal-ui,browser等,具体含义请见文末拓展阅读
"icons": [
{
"src": "icon.png",
"sizes": "192x192",
"type": "image/png"
}
], //这里举例了应用图片的配置,可以配置多个图标!
"name": "Awesome fox pictures", //应用的名称,在安装时展示
"short_name": "Foxes", //缩略名,一般在添加到桌面之后会展示这个名字
"start_url": "/" //启动后进入的
}
然后将本文件保存为manifest.json并放置在网站根目录,并在网站
标签内添加以下内容:<link rel="manifest" href="manifest.webmanifest">
Safari浏览器对PWA支持并不完善,如果需要正确的展示PWA应用,需要将以下代码根据实际情况调整后添加在
标签内:<link rel="shortcut icon" href="favicon.ico">
<link rel="shortcut icon" href="src to icon" type="image/x-icon" />
<link rel="apple-touch-icon" href="src to icon" />
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-title" content="Web App Name">
配置Service Worker
接下来是Service Worker的代码,将其命名为sw.js并保存。
// sw.js
var cacheStorageKey = 'poem-0.0.2'
var cacheList = []
self.addEventListener('install', e => { // install 事件,它发生在浏览器安装并注册 Service Worker 时
// e.waitUtil 用于在安装成功之前执行一些预装逻辑
e.waitUntil(
caches.open(cacheStorageKey)
.then(cache => cache.addAll(cacheList))
.then(() => self.skipWaiting())
)
})
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('activated', 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()
})
)
})
sw.js 的内容基本是从网上拷贝的。这个文件会运行在 service worker 线程中,并且会拦截各种网络请求。文件中监听的 fetch 事件回调就是对请求进行的处理。我这里会尝试从缓存获取,如果缓存没有才发起请求。在一开始,我将跟路径“/”添加到了 cacheList 中。其结果是首页被缓存,导致后续发版无法更新。还好当时是本地测试,在浏览器开发工具 application 面板清除缓存并将 cacheList 置空后,问题迎刃而解。当然,这种做法并不好,实际上可以通过检测缓存版本解决。不过,算了,我只是需要将网站添加到桌面。
对于只需要添加桌面图标,不需要缓存内容,我找到了更简单的版本。
const cacheName = 'kodcloud';
const staticAssets = [];
self.addEventListener('install', async e => {
});
self.addEventListener('activate', e => {
self.clients.claim();
});
self.addEventListener('fetch', async e => {
});
注册Service Worker
首先编写index.js,这部分内容也可以直接编写在网页的<script>标签中。
if(navigator.serviceWorker != null){
navigator.serviceWorker.register('sw.js',{scope: '/'})
.then(function(registartion){
//注册成功
console.log('支持sw:',registartion.scope)
}).catch(function (err){
console.log('fail')
});
}
至此,大功告成。
本文共 955 个字数,平均阅读时长 ≈ 3分钟
评论 (0)