progressive web app
问:为什么说它就是渐进式的呢?什么是渐进式? 答:渐进增强,新技术没有完全普及,先应用普及的技术。与优雅降级相反,优雅降级,是先应用所有新技术,保证在最新浏览器中成功应用,然后再慢慢降级,实现低版本浏览器兼容
目录
待实现功能:
具有明确uri的资源:cache api
所有其他数据:indexedDB
本步骤将实现添加站到到应用首屏,包括应用图标、启动页、独立应用等
创建一个 manifest.json
文件,内容格式如下
{
"name": "character search", // 打开后网页名称
"short_name": "password", // 图标下的名称
"icons": [
{
"src": "/android-chrome-192x192.png",
"sizes": "192x192",
"type": "image/png"
},
{
"src": "/android-chrome-512x512.png",
"sizes": "512x512",
"type": "image/png"
}
],
"start_url": "./index.html", // 默认加载页
"theme_color": "#181743", // 主题
"background_color": "#141415", // 启动背景颜色
"display": "standalone" // 启动类型,通常设置 standalone、fullscreen
}
关键点:
meta
值一定要跟 manifest
中的值一致在应用入口文件 index.html
中引入 manifest.json
<link rel="manifest" href="/manifest.json">
奈何这是浏览器自己实现的,目前我也控制不了
通过 service worker
+ cache storage
实现缓存(可以查看web存储)
if ('serviceWorker' in navigator) {
window.addEventListener('load', function() {
navigator.serviceWorker.register('/sw-test/sw.js', { scope: '/sw-test/' }).then(function(reg) {
if(reg.installing) {
console.log('Service worker installing');
} else if(reg.waiting) {
console.log('Service worker installed');
} else if(reg.active) {
console.log('Service worker active');
}
}).catch(function(error) {
// registration failed
console.log('Registration failed with ' + error);
});
}
}
const version = 'v2'
const cachedFiles = [
'/',
'/index.html',
'/app.js'
]
self.addEventListener('install', function(event) {
event.waitUntil(self.skipWaiting());
});
self.addEventListener('fetch', function(event) {
event.respondWith(caches.match(event.request).then(function(response) {
if (response !== undefined) {
return response;
} else {
return fetch(event.request).then(function (response) {
if(!response || response.status !== 200) {
return response
}
let responseClone = response.clone();
caches.open(version).then(function (cache) {
cache.put(event.request, responseClone);
});
return response;
}).catch(function (e) {
return e;
});
}
}));
});
更新主要是用于清除之前service worker缓存的文件,我要缓存新文件了
self.addEventListener('activate', function (event) {
event.waitUntil(
Promise.all([
self.clients.claim(),
caches.keys().then(function (cacheList) {
return Promise.all(
cacheList.map(function (cacheName) {
if (cacheName !== version) {
return caches.delete(cacheName);
}
})
);
})
])
);
});
对于具有明确 uri 的资源,采用 cache api 实现缓存(ajax请求数据可以缓存),对于其他数据,使用 indexedDB
关键点:在执行添加到主屏幕之前,要保证service worker的缓存执行完毕,这就需要做个引导添加,时机如何选择呢?如果缓存没有执行完毕,那么添加到主屏幕的应用,下次打开方式还是通过浏览器打开的。
参考文章