Skip to content

Commit

Permalink
[v2] [gatsby-plugin-offline] fix: improve service worker initial cach…
Browse files Browse the repository at this point in the history
…ing (#8183)

* Upgrade packages

* Use push messages to fetch resources

* Resolve the promises properly

* Use NetworkFirst for external resources

* Change "type" to "api"

* Fix integration test
  • Loading branch information
vtenfys authored and m-allanson committed Sep 17, 2018
1 parent 8c41fe2 commit 68d2fb1
Show file tree
Hide file tree
Showing 7 changed files with 1,263 additions and 1,541 deletions.
2 changes: 1 addition & 1 deletion jest.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,5 +29,5 @@ module.exports = {
},
// TODO: Remove this once https://github.com/facebook/jest/pull/6792 is released.
// Probably in Jest 23.4.3
testURL: 'http://localhost',
testURL: `http://localhost`,
}
3 changes: 3 additions & 0 deletions jest.integration.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,7 @@ module.exports = {
],
transform: { "^.+\\.js$": `<rootDir>/jest-transformer.js` },
verbose: true,
// TODO: Remove this once https://github.com/facebook/jest/pull/6792 is released.
// Probably in Jest 23.4.3
testURL: `http://localhost`,
}
24 changes: 11 additions & 13 deletions packages/gatsby-plugin-offline/src/gatsby-browser.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ exports.onPrefetchPathname = ({ pathname }) => {
}
}

exports.onServiceWorkerInstalled = ({ getResourceURLsForPathname }) => {
exports.onServiceWorkerActive = ({ getResourceURLsForPathname, serviceWorker }) => {
// stop recording prefetch events
swNotInstalled = false

Expand All @@ -28,19 +28,17 @@ exports.onServiceWorkerInstalled = ({ getResourceURLsForPathname }) => {
.call(nodes)
.map(node => node.src || node.href || node.getAttribute(`data-href`))

for (const resource of resources) {
const url = new URL(resource, window.location.origin)
const isExternal = url.origin !== window.location.origin
fetch(
resource,
isExternal ? { mode: `no-cors` } : undefined
)
}

// Loop over all resources and fetch the page component and JSON
// to add it to the sw cache.
prefetchedPathnames.forEach(path => {
const urls = getResourceURLsForPathname(path)
urls.forEach(url => fetch(url))
const prefetchedResources = []
prefetchedPathnames.forEach(path =>
getResourceURLsForPathname(path).forEach(resource =>
prefetchedResources.push(resource)
)
)

serviceWorker.active.postMessage({
api: `gatsby-runtime-cache`,
resources: [...resources, ...prefetchedResources],
})
}
9 changes: 9 additions & 0 deletions packages/gatsby-plugin-offline/src/gatsby-node.js
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,11 @@ exports.onPostBuild = (args, pluginOptions) => {
urlPattern: /\.(?:png|jpg|jpeg|webp|svg|gif|tiff|js|woff|woff2|json|css)$/,
handler: `staleWhileRevalidate`,
},
{
// Use the Network First handler for external resources
urlPattern: /^https:/,
handler: `networkFirst`,
},
],
skipWaiting: true,
clientsClaim: true,
Expand All @@ -117,6 +122,10 @@ exports.onPostBuild = (args, pluginOptions) => {
.generateSW({ swDest, ...combinedOptions })
.then(({ count, size, warnings }) => {
if (warnings) warnings.forEach(warning => console.warn(warning))

const swAppend = fs.readFileSync(`${__dirname}/sw-append.js`)
fs.appendFileSync(`public/sw.js`, swAppend)

console.log(
`Generated ${swDest}, which will precache ${count} files, totaling ${size} bytes.`
)
Expand Down
23 changes: 23 additions & 0 deletions packages/gatsby-plugin-offline/src/sw-append.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/* global workbox */

self.addEventListener(`message`, event => {
const { api } = event.data
if (api === `gatsby-runtime-cache`) {
const { resources } = event.data
const cacheName = workbox.core.cacheNames.runtime

event.waitUntil(
caches.open(cacheName).then(cache =>
Promise.all(
resources.map(resource =>
cache.add(resource).catch(e => {
// ignore TypeErrors - these are usually due to
// external resources which don't allow CORS
if (!(e instanceof TypeError)) throw e
})
)
)
)
)
}
})
8 changes: 2 additions & 6 deletions packages/gatsby/cache-dir/register-service-worker.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,7 @@ if (`serviceWorker` in navigator) {
// Post to service worker that install is complete.
// Delay to allow time for the event listener to be added --
// otherwise fetch is called too soon and resources aren't cached.
window.setTimeout(() => {
apiRunner(`onServiceWorkerInstalled`, {
serviceWorker: reg,
})
}, 100)
apiRunner(`onServiceWorkerInstalled`, { serviceWorker: reg })
}
break

Expand All @@ -39,7 +35,7 @@ if (`serviceWorker` in navigator) {
apiRunner(`onServiceWorkerRedundant`, { serviceWorker: reg })
break

case `active`:
case `activated`:
apiRunner(`onServiceWorkerActive`, { serviceWorker: reg })
break
}
Expand Down
Loading

0 comments on commit 68d2fb1

Please sign in to comment.