Workbox Webpack Plugin安装后未从缓存加载JS资源求助
解决Laravel Mix + PWA后续刷新不使用缓存的问题
我基于Laravel 5.8与Vue.js 2.5搭建PWA应用,Service Worker已正确安装,首次加载能缓存资源,但后续页面刷新时总是从网络重新加载,无法实现PWA安装后的快速初始加载(此前用Angular PWA模块可实现缓存加载+后续更新的效果)。以下是当前mix.js的配置:
... mix.js('resources/js/app.js', 'public/js') .generateSW({ // Define runtime caching rules. runtimeCaching: [{ // Match any request that ends with .png, .jpg, .jpeg or .svg. urlPattern: /\.(?:png|jpg|jpeg|svg)$/, // Apply a cache-first strategy. handler: 'CacheFirst', options: { // Use a custom cache name. cacheName: 'images', // Only cache 10 images. expiration: { maxEntries: 10, }, }, }], skipWaiting: true }) .vue() .copy('node_modules/lodash/lodash.min.js', 'public/js') .copy('./resources/manifest.json', 'public/dist/manifest.json') .copy('./resources/icons', 'public/dist/') .extract(['vue']) .webpackConfig({ output: { filename: '[name].js', chunkFilename: `[name].chunk.[contenthash:8].js`, path: path.join(__dirname, 'public/dist'), publicPath: '/dist/' }, resolve: { alias: { 'vue$': 'vue/dist/vue.common.js', 'variables': path.resolve('resources/sass/_variables.scss') } }, plugins: [ new webpack.ContextReplacementPlugin( /moment[\/\\]locale$/, /(en|es)$/ ), ] }) .options({ processCssUrls: false, }); ...
问题根源
当前generateSW仅配置了图片的运行时缓存规则,但HTML、JS、CSS等核心初始资源未被加入预缓存列表,也没有对应的缓存策略覆盖这些资源的请求,导致刷新时这些关键资源只能走网络请求,无法利用缓存实现快速加载。
解决步骤
1. 扩展generateSW的缓存规则与预缓存配置
修改generateSW选项,添加核心资源的缓存策略,并确保预缓存列表包含必要文件:
.generateSW({ runtimeCaching: [ // 保留原图片缓存规则 { urlPattern: /\.(?:png|jpg|jpeg|svg)$/, handler: 'CacheFirst', options: { cacheName: 'images', expiration: { maxEntries: 10, }, }, }, // 新增核心资源(HTML/JS/CSS)缓存规则 { urlPattern: /\.(?:html|js|css)$/, handler: 'StaleWhileRevalidate', // 优先用缓存,后台异步更新缓存 options: { cacheName: 'core-assets', expiration: { maxAgeSeconds: 30 * 24 * 60 * 60, // 缓存有效期30天 }, cacheableResponse: { statuses: [0, 200], // 支持缓存CORS请求与成功响应 }, }, }, // 根路径请求(首页)单独配置 { urlPattern: '/', handler: 'StaleWhileRevalidate', options: { cacheName: 'core-assets', }, } ], skipWaiting: true, clientsClaim: true, // SW激活后立即接管所有打开的页面 include: [/\.html$/, /\.js$/, /\.css$/], // 指定预缓存的文件类型 exclude: [/\.map$/, /hot-update\.js$/], // 排除无需缓存的文件(如sourcemap) swDest: 'public/dist/sw.js', // 指定SW文件输出路径,与webpack输出目录匹配 })
2. 修正资源路径配置
将manifest.json移到public根目录(避免路径识别问题):
.copy('./resources/manifest.json', 'public/manifest.json')
3. 验证缓存效果
修改配置后重新执行构建命令:
npm run production
然后通过Chrome DevTools验证:
- 进入
Application > Service Workers,确认SW处于激活状态且clientsClaim生效 - 查看
Cache Storage中的core-assets与images列表,确认包含对应的资源文件 - 断开网络后刷新页面,若能正常加载则说明缓存策略生效
内容的提问来源于stack exchange,提问作者Conde
相关产品推荐
相关产品推荐

