Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[offline-plugin] Add support for SW caching of prefetched resources #6566

Merged
merged 7 commits into from
Jul 24, 2018

Conversation

kkemple
Copy link
Contributor

@kkemple kkemple commented Jul 19, 2018

This PR includes:

  • a fix for non-cached preset assets
    • Current strategy for catching prefetched assets is to record prefetches until SW is installed, then simply fetch them in the background so they are added to runtime cache by SW.
  • new API hooks for service worker events
  • migration to workbox
    • set custom cache names so plugins can tie in easily
  • document new APIs
  • update docs for onPrefetchPathname callback arguments
  • prevent caching of .xml files

Closes #6378
Closes #6081
Closes #6652

@KyleAMathews
Copy link
Contributor

KyleAMathews commented Jul 19, 2018

Deploy preview for using-postcss-sass failed.

Built with commit 9324b6b

https://app.netlify.com/sites/using-postcss-sass/deploys/5b579703e39e7c41df755bd7

if (`serviceWorker` in navigator) {
navigator.serviceWorker.controller.postMessage({
type: `prefetch`,
...pathData,
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what needs to be done to this data before we can pass on to SW?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

docs look unclear on what is actually passed, an issue could be opened to fix as well, let me know if we want that!

https://next.gatsbyjs.org/docs/browser-apis/#onPrefetchPathname

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What needs cached is the code/data files for each path that's prefetched. I can't remember off-hand what is passed to onPrefetchPathname. If the actual URLs are passed, there's an internal API on loader.js I believe for getting those resource paths.

Importantly though we only need to record prefetching until the SW is loaded as then it'll start caching itself. SW's have lifecycle events which we track here: https://github.com/gatsbyjs/gatsby/blob/master/packages/gatsby/cache-dir/register-service-worker.js

What I think we should do is send those events out via api-runner-browser so that then plugins like this one could listen to them. Then you just have a boolean like swNotLoaded which defaults to false and while it's false, it queues up page resources and then once the sw loads, it stops listening to prefetching (as the SW is now) and sends all the page resources to the SW to cache them there.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

docs look unclear on what is actually passed, an issue could be opened to fix as well, let me know if we want that!

That'd be great too!

@@ -0,0 +1,6 @@
self.addEventListener(`message`, async ({ data }) => {
if (data.type === `prefetch`) {
const cache = await caches.open(`runtimecache`)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

need to figure out the proper name of cache

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can look in the Chrome "application" tab for the name of the cache. Also probably worth looking through the sw-precache docs to see if they talk about this use case of explicitly caching resources from the client.

Copy link
Contributor Author

@kkemple kkemple Jul 20, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i checked and couldn't find anything, workbox docs have it and wonder if it's the same, at worst case i can dig through source code or look at application tab

@gatsbybot
Copy link
Collaborator

Deploy preview for using-drupal ready!

Built with commit 95fccb8

https://deploy-preview-6566--using-drupal.netlify.com

@kkemple kkemple self-assigned this Jul 19, 2018
@gatsbybot
Copy link
Collaborator

Deploy preview for gatsbygram ready!

Built with commit 95fccb8

https://deploy-preview-6566--gatsbygram.netlify.com

@gatsbybot
Copy link
Collaborator

gatsbybot commented Jul 19, 2018

Deploy preview for using-drupal ready!

Built with commit 9324b6b

https://deploy-preview-6566--using-drupal.netlify.com

@gatsbybot
Copy link
Collaborator

gatsbybot commented Jul 19, 2018

Deploy preview for gatsbygram ready!

Built with commit 9324b6b

https://deploy-preview-6566--gatsbygram.netlify.com

@kkemple kkemple force-pushed the topics/offline-plugin-improvements branch from b94163c to 4fe78a0 Compare July 24, 2018 18:30
@kkemple kkemple changed the title WIP: add support for sw caching prefetched resources Add support for sw caching prefetched resources Jul 24, 2018
@kkemple kkemple changed the title Add support for sw caching prefetched resources [offline-plugin] Add support for sw caching prefetched resources Jul 24, 2018
@kkemple kkemple changed the title [offline-plugin] Add support for sw caching prefetched resources [offline-plugin] Add support for SW caching of prefetched resources Jul 24, 2018
@KyleAMathews
Copy link
Contributor

KyleAMathews commented Jul 24, 2018

Deploy preview for gatsbyjs failed.

Built with commit 9324b6b

https://app.netlify.com/sites/gatsbyjs/deploys/5b579702e39e7c41df755bcf

Copy link
Contributor

@KyleAMathews KyleAMathews left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some small tweaks needed I think but otherwise looks fantastic!

let swNotInstalled = true
const pathnameResources = []

exports.onPrefetchPathname = ({ pathname, getResourcesForPathname }) => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This could use a comment to explain that here we record resources that are prefetched before the sw has been installed and can cache things directly.

)

// get all script URLs
const scripts = [].slice
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ol' skool dom hacking

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

😎


if (`serviceWorker` in navigator) {
navigator.serviceWorker
.register(`${__PATH_PREFIX__}/sw.js`)
.then(function(reg) {
reg.addEventListener(`updatefound`, () => {
apiRunner(`onServiceWorkerUpdateFound`)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

let's pass in reg as an option (though maybe call it just serviceWorker to all the API calls in case plugins want access to it.

@kkemple kkemple force-pushed the topics/offline-plugin-improvements branch from 74d4298 to c50ff4c Compare July 24, 2018 21:12
Copy link
Contributor

@KyleAMathews KyleAMathews left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎉 This is fantastic and fixes some new problems we've had with v2 offline plugin & some existing ones carried over from v1.

@KyleAMathews KyleAMathews merged commit d1f1ef1 into master Jul 24, 2018
@KyleAMathews KyleAMathews deleted the topics/offline-plugin-improvements branch July 24, 2018 21:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment