Appearance
PWA 相关知识点
Web App Manifest
描述应用的 JSON 文件,通知支持 pwa 的浏览器将应用添加到主屏 web-app-manifest
在静态资源目录下新建
manifest.jsonjson{ "name": "xx Web APP", // 启动过程中显示的文案 "short_name": "xxx", // 显示在主屏 app 图标下的文案 "description": "一个 xxx APP", // 描述应用的文案 "icons": [ { // 小的显示在主屏上,大的显示在安装过程中 "src": "https://static.xxx.com/img/48.png", "sizes": "48x48", "type": "image/png" }, { "src": "https://static.xxx.com/img/192.png", "sizes": "192x192", "type": "image/png" } ], "start_url": "/?utm_source=homescreen", // 主屏启动进入的页面路径 - utm_source 可用于统计流量来源 "display": "standalone", // 定义浏览器 UI - standalone 全屏 "orientation": "portrait", // 竖屏 "background_color": "#f2f2f2", // 背景色 "theme_color": "#000" // 主题色 }html里引入html<link rel="manifest" href="/static/manifest.json" />
ga埋点统计添加到主屏的用户jswindow.addEventListener('beforeinstallprompt', function (e) { window.ga('send', 'event', 'pwa', 'addToScreen', 'installprompt', 1) e.userChoice.then(function (choiceResult) { window.ga('send', 'event', 'pwa', 'addToScreen', choiceResult.outcome, 1) }) })
service workers
缓存策略等 Workbox
创建(构建)
service-worker.jsnode 脚本构建
npm install workbox-build -D先创建好
service-worker.jsjs// -> src/service-worker.js workbox.precaching.precacheAndRoute([]) // 后面脚本会在 [] 插入 // ... // workbox.routing -> Reg 匹配静态 or 动态路由的缓存策略执行脚本
jsconst workboxBuild = require('workbox-build') workboxBuild .injectManifest({ swSrc: 'src/service-worker.js', // 上面建好的文件 swDest: 'dist/service-worker.js', // 输出的文件 globDirectory: '/dist/static/', globPatterns: ['**/*.{js,css}', '**/img/*.{jpg,png,ico}'], // 匹配要缓存的 globIgnores: ['service-worker.js'], // 忽略的 // 配置资源路径前缀(如果静态资源部署到单独服务器的话会有用) modifyUrlPrefix: { '': config.build.assetsPublicPath }, }) .then(({ count, size, warnings }) => { warnings.forEach(console.warn) console.log(`${count} files will be precached, totaling ${size} bytes.`) })
webpack 构建
npm install workbox-webpack-plugin -D先创建
service-worker.jsjs// ... 插件会在这里插入 self.__precacheManifest 变量和依赖 // precaching -> webpack 打包后的资源缓存 workbox.precaching.suppressWarnings() workbox.precaching.precacheAndRoute(self.__precacheManifest, {}) // ... // workbox.routing -> Reg 匹配静态 or 动态路由的缓存策略webpack 插件配置 webpack-chain
require('workbox-webpack-plugin').InjectManifest同workboxBuild.injectManifestjsconst { InjectManifest } = require('workbox-webpack-plugin') // InjectManifest 参数同上 config.plugin('pwa').use(InjectManifest, [ { swSrc: 'src/service-worker.js', importsDirectory: './dist/js', exclude: [/\.html$/], // ... }, ])缓存策略
静态资源预缓存
precacheAndRoute- 根据资源文件内容生成 hash 版本号,文件变化后自动更新缓存
workbox.routing
cacheFirstjsworkbox.routing.registerRoute( new RegExp(/123/), // 匹配路由 workbox.strategies.cacheFirst({ // 缓存优先 cacheName: 'cross-cache', // 后台缓存的 key plugins: [ new workbox.expiration.Plugin({ maxEntries: 100, // 缓存最大数 maxAgeSeconds: 30 * 24 * 60 * 60, // 过期 }), ], }) )NetworkFirst网络优先StaleWhileRevalidate缓存、网络竞速NetworkOnlyCacheOnly
注册
service-worker.js(上面生成的)需尽可能早的执行
jsif (location.protocol === 'https:' && 'serviceWorker' in navigator) { navigator.serviceWorker .register('/service-worker.js') .then(function (registration) { console.log('Service Worker scope: ', registration.scope) }) .catch(function (err) { console.log(err) }) }