Summary of workbox practice
The following is just a summary of practice, if you have better suggestions, please leave a message.
package.json
Compilation is divided into two parts (using the test environment as an example) :
- Build test packages
- Create the sw.js file
{ "scripts": { "test": "vue-cli-service build --mode test"."build:pwa": "node ./workbox-build/workbox-build-inject.js"."build:test:web": "npm run test && npm run build:pwa"}}Copy the code
Write the sw.js file
importScripts('https://storage.googleapis.com/workbox-cdn/releases/6.1.1/workbox-sw.js')
workbox.loadModule('workbox-precaching')
workbox.loadModule('workbox-routing')
workbox.loadModule('workbox-strategies')
workbox.loadModule('workbox-expiration')
const { cleanupOutdatedCaches, precacheAndRoute } = workbox.precaching
const { registerRoute } = workbox.routing
const { CacheFirst, StaleWhileRevalidate } = workbox.strategies
const { ExpirationPlugin } = workbox.expiration
const DAY_IN_SECONDS = 24 * 60 * 60
const MONTH_IN_SECONDS = DAY_IN_SECONDS * 30
// precache
cleanupOutdatedCaches()
const assetsToCache = self.__WB_MANIFEST
precacheAndRoute(assetsToCache)
// routes
registerRoute(/ \. (? :js|css)$/.new StaleWhileRevalidate())
registerRoute(
/ \. (? :png|gif|jpg|jpeg|svg)$/.new CacheFirst({
cacheName: 'images-cache'.plugins: [
new ExpirationPlugin({
maxEntries: 250.maxAgeSeconds: MONTH_IN_SECONDS
})
]
})
)
self.addEventListener('message'.(event) = > {
if (event && event.data) {
console.debug(`Skipping waiting... `, event.data)
if (event.data === 'SKIP_WAITING') {
console.debug(`Skipping waiting... `)
self.skipWaiting()
self.clients.claim()
}
}
})
Copy the code
About the Workbox-build directory
workbox-build/workbox-build-inject.js
const { injectManifest } = require('workbox-build')
const workboxConfig = require('./workbox-config')
injectManifest(workboxConfig).then(({ count, size }) = > {
console.log(`Generated ${workboxConfig.swDest}, which will precache ${count} files (${size} bytes)`)})Copy the code
workbox-build/workbox-config.js
const path = require('path')
function resolve(dir) {
return path.join(__dirname, dir)
}
module.exports = {
swSrc: resolve('.. /sw.js'),
swDest: resolve('.. /dist/sw.js'),
globDirectory: resolve('.. /dist'),
globPatterns: ['vendor/*.js']}Copy the code
Conclusion practice
- Create a vendor file for infrequently changing resources (e.g., third-party dependencies on Vue, vuex, Lodash, Axios, etc.) as precache cache (cached during the install phase of the service-worker) for matching cached resources, Read directly from the cache.
- The precache cache is configured by workbox-config.js and generated by the placeholder self.__wb_manifest in sw.js.
- Offline allows HTML access
const defaultRouteHandler = createHandlerBoundToURL('/index.html')
const defaultNavigationRoute = new NavigationRoute(defaultRouteHandler, {
// allowlist: [],
// denylist: [],
})
registerRoute(defaultNavigationRoute)
Copy the code
Work with the configuration in workbox-config.js
globPatterns: ['vendor/*.js'.'**/*.html']
Copy the code
However, it should be noted that if the HTML is cached, the page needs to be refreshed again after the SW is activated to update the HTML, because the cached HTML introduces the old resources. Instead of caching, the cached HTML directly requests the new files and then caches (stale-while-revalidate) the files. Falling back to the network request if it’s not cached)
- For JS and CSS, the cache policy is stale-while-revalidate. If there is any in the cache, the cache response should be used as soon as possible, and then the network request should be used to update the cache. If there is no cache, fall back to the network request. This strategy ensures that users are responding as quickly as possible and that the files are updated as early as possible.
- For image resources such as. PNG,. GIF, and. JPG, use the cache first policy and set the validity period.