1.什么是pwa?
PWA全称Progressive Web App,即渐进式WEB应用。
一个 PWA 应用首先是一个网页, 可以通过 Web 技术编写出一个网页应用. 随后添加上 App Manifest 和 Service Worker 来实现 PWA 的安装和离线等功能
2.说一下有用的资料:
Google Workbox 组件: https://developers.google.com/web/tools/workbox
pwa之 Workbox学习:https://segmentfault.com/a/1190000019281388?utm_source=tag-newest
pwabuilder :https://www.pwabuilder.com/serviceworker
pwa-update:https://github.com/pwa-builder/pwa-update
上面的资料有些访问不了,那很抱歉可能是需要网络翻墙才可以看。
3.了解用pwa达到的目的
开始接触这个pwa,一直不明白要达到怎样的效果。其实就是缓存住网页所有内容,让网页快速重复打开速度提升,并且在网络不好的情况可以脱机浏览,没有浏览过的页面会提示网络连接中断的字样。
目前我用到的是缓存功能+离线提示页面。
建议用pwabuilder 简单的尝试pwa运行用法,及调试方法。
4.next-pwa npm
由于网站用的next.js,所以找了如下资料:
progressive-web-app官方案例::https://github.com/vercel/next.js/tree/canary/examples/progressive-web-app
next-pwa案例集合: https://github.com/shadowwalker/next-pwa/tree/master/examples
5.配置next-pwa
npm i next-pwa --save
//next.config.js
const withPWA = require('next-pwa');
module.exports = withPWA({
pwa: {
dest: 'public',
swSrc: 'service-worker.js',
register: true
}
})
//service-worker.js建议放在根目录
import { skipWaiting, clientsClaim } from 'workbox-core'
import { ExpirationPlugin } from 'workbox-expiration'
import { NetworkOnly, NetworkFirst, CacheFirst, StaleWhileRevalidate } from 'workbox-strategies'
import { registerRoute, setDefaultHandler, setCatchHandler } from 'workbox-routing'
import { matchPrecache, precacheAndRoute, cleanupOutdatedCaches } from 'workbox-precaching'
skipWaiting()
clientsClaim()
// must include following lines when using inject manifest module from workbox
// https://developers.google.com/web/tools/workbox/guides/precache-files/workbox-build#add_an_injection_point
const WB_MANIFEST = self.__WB_MANIFEST
// Precache fallback route and image
WB_MANIFEST.push(
{
url: '/offline', //这里是重点,主要方式断网后呈现的自定义页面(page/offline.js)
revision: '1234567890'
}
)
precacheAndRoute(WB_MANIFEST)
cleanupOutdatedCaches()
registerRoute(
'/',
new NetworkFirst({
cacheName: 'start-url',
plugins: [new ExpirationPlugin({ maxEntries: 1, maxAgeSeconds: 86400, purgeOnQuotaError: !0 })]
}),
'GET'
)
registerRoute(
/^https:\/\/fonts\.(?:googleapis|gstatic)\.com\/.*/i,
new CacheFirst({
cacheName: 'google-fonts',
plugins: [new ExpirationPlugin({ maxEntries: 4, maxAgeSeconds: 31536e3, purgeOnQuotaError: !0 })]
}),
'GET'
)
registerRoute(
/\.(?:eot|otf|ttc|ttf|woff|woff2|font.css)$/i,
new StaleWhileRevalidate({
cacheName: 'static-font-assets',
plugins: [new ExpirationPlugin({ maxEntries: 4, maxAgeSeconds: 604800, purgeOnQuotaError: !0 })]
}),
'GET'
)
// disable image cache, so we could observe the placeholder image when offline
registerRoute(
/\.(?:jpg|jpeg|gif|png|svg|ico|webp)$/i,
new NetworkOnly({
cacheName: 'static-image-assets',
plugins: [new ExpirationPlugin({ maxEntries: 64, maxAgeSeconds: 86400, purgeOnQuotaError: !0 })]
}),
'GET'
)
registerRoute(
/\.(?:js)$/i,
new StaleWhileRevalidate({
cacheName: 'static-js-assets',
plugins: [new ExpirationPlugin({ maxEntries: 32, maxAgeSeconds: 86400, purgeOnQuotaError: !0 })]
}),
'GET'
)
registerRoute(
/\.(?:css|less)$/i,
new StaleWhileRevalidate({
cacheName: 'static-style-assets',
plugins: [new ExpirationPlugin({ maxEntries: 32, maxAgeSeconds: 86400, purgeOnQuotaError: !0 })]
}),
'GET'
)
registerRoute(
/\.(?:json|xml|csv)$/i,
new NetworkFirst({
cacheName: 'static-data-assets',
plugins: [new ExpirationPlugin({ maxEntries: 32, maxAgeSeconds: 86400, purgeOnQuotaError: !0 })]
}),
'GET'
)
registerRoute(
/\/api\/.*$/i,
new NetworkFirst({
cacheName: 'apis',
networkTimeoutSeconds: 10,
plugins: [new ExpirationPlugin({ maxEntries: 16, maxAgeSeconds: 86400, purgeOnQuotaError: !0 })]
}),
'GET'
)
registerRoute(
/.*/i,
new NetworkFirst({
cacheName: 'others',
networkTimeoutSeconds: 10,
plugins: [new ExpirationPlugin({ maxEntries: 32, maxAgeSeconds: 86400, purgeOnQuotaError: !0 })]
}),
'GET'
)
// following lines gives you control of the offline fallback strategies
// https://developers.google.com/web/tools/workbox/guides/advanced-recipes#comprehensive_fallbacks
// Use a stale-while-revalidate strategy for all other requests.
setDefaultHandler(new StaleWhileRevalidate())
// This "catch" handler is triggered when any of the other routes fail to
// generate a response.
setCatchHandler(({ event }) => {
// The FALLBACK_URL entries must be added to the cache ahead of time, either
// via runtime or precaching. If they are precached, then call
// `matchPrecache(FALLBACK_URL)` (from the `workbox-precaching` package)
// to get the response from the correct cache.
//
// Use event, request, and url to figure out how to respond.
// One approach would be to use request.destination, see
// https://medium.com/dev-channel/service-worker-caching-strategies-based-on-request-types-57411dd7652c
switch (event.request.destination) {
case 'document':
// If using precached URLs:
return matchPrecache('/offline');
// return caches.match('/fallback')
break
case 'image':
// // If using precached URLs:
// return matchPrecache('/static/images/fallback.png');
// // return caches.match('/static/images/fallback.png')
// break
case 'font':
// If using precached URLs:
// return matchPrecache(FALLBACK_FONT_URL);
//return caches.match('/static/fonts/fallback.otf')
//break
default:
// If we don't have a fallback, just return an error response.
return Response.error()
}
})
next-pwa只会在发布后有效果,开发环境会影响页面缓慢,建议开发环境停用。
运行:
npm run build
npm run start
next-pwa会自动在public文件里面生成sw.js文件。