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

Precaching temp #1342

Merged
merged 5 commits into from Mar 5, 2018
Merged

Precaching temp #1342

merged 5 commits into from Mar 5, 2018

Conversation

gauntface
Copy link

Fixes #1316

Precaching first occurs into a cache with -temp appended to the end and during the activate step I copy the requests over to the originally intended cache.

For the most part this seems like a minor and safe change. I extended the test that installs and activates two sets of assets to ensure new expectations are being met, there was a bug in the cache API where keys weren't updated and the integration test had a weird issue with Firefox where multiple activate events seem to enter into a race condition and we can't rely on the cache cleanup being done by the time the client is claimed.

Let me know what you thinkg

@gauntface
Copy link
Author

I ended up changing the activateSW method to actually wait for the service worker to activate (vs waiting for when a service worker claims a client.

The reason for this is that a set of the precaching tests rely on being run after the activation logic has finished, which isn't true if we are waiting on the controllerchange event instead.

@coveralls
Copy link

coveralls commented Mar 3, 2018

Coverage Status

Coverage increased (+0.03%) to 88.356% when pulling 99ae898 on precaching-temp into 047aac5 on v3.

Copy link
Contributor

@jeffposnick jeffposnick left a comment

Choose a reason for hiding this comment

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

Thanks for dealing with this!

}

navigator.serviceWorker.register(swUrl)
Copy link
Contributor

Choose a reason for hiding this comment

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

The background on why we were waiting for the correct SW to take control, rather than waiting on activation, is in w3c/ServiceWorker#799 (comment)

We've seen flakiness in unit tests in the past due to the small window of time in between when a service worker activates and when it takes control of a window client. If the window client makes a network request in that window of time, the correct service worker won't intercept it.

Copy link
Author

Choose a reason for hiding this comment

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

So I saw flakiness the other way, so how about we check for both?

Copy link
Contributor

Choose a reason for hiding this comment

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

Can we dig into the flakiness you saw in the other direction? Potentially outside of this PR, if you can restore the previous logic and supplement it with the additional logic that's now necessarily.

FWIW, a scenario in which a SW can take control of a page before it's been activated sounds like a (potentially serious) browser bug.

Copy link
Author

Choose a reason for hiding this comment

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

Spoke to @jakearchibald about this as I don't think it is a bug.

Having multiple evens, one claiming and others doing work means:

All clients will be claimed straight away, but the service worker won't activate until promises passed to waitUntil resolve

This makes sense to me but does bring in to question whether we should do some other magic around clientsClaim to account for this.

Copy link
Contributor

Choose a reason for hiding this comment

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

Wait, really? My understanding was that the service worker couldn't take control of a client until after it activated. Huh.

const requests = await tempCache.keys();
await Promise.all(requests.map(async (request) => {
const response = await tempCache.match(request);
await cacheWrapper.put(this._cacheName, request, response);
Copy link
Contributor

Choose a reason for hiding this comment

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

We have #1312 open to track the larger question of how to deal with quota issues that come up during precaching.

In the meantime, this PR introduces some overhead due to every response in the temp cache being duplicated first, and with all the temp entries only getting deleted after all of those duplicates are written.

What if you added in

await cacheWrapper.delete(this._getTempCacheName(), request);

inside this loop, to clear out the temporary copy of each individual response after it's been duplicated to the final cache?

You can still leave the

await caches.delete(this._getTempCacheName());

outside the loop, to delete the cache itself, though at that point the cache should have 0 entries in it.

@gauntface
Copy link
Author

@jeffposnick this has the changes you mentioned (good thinking on the clearing the temp cache as we go). There isn't currently a cacheWrapper delete function and not sure we should add one this late in the game for v3.

Also changed the activate logic to wait for activate to finish and then check the current controller.

@workbox-pr-bot
Copy link
Collaborator

PR-Bot Size Plugin

Changed File Sizes

File Before After Change GZipped
packages/workbox-precaching/build/workbox-precaching.prod.js 5.26 KB 5.65 KB +8% 2.15 KB

New Files

No new files have been added.

All File Sizes

View Table
File Before After Change GZipped
packages/workbox-background-sync/build/workbox-background-sync.prod.js 3.52 KB 3.52 KB 0% 1.45 KB
packages/workbox-broadcast-cache-update/build/workbox-broadcast-cache-update.prod.js 1.13 KB 1.13 KB 0% 589 B
packages/workbox-build/build/_types.js 41 B 41 B 0% 61 B
packages/workbox-build/build/index.js 2.52 KB 2.52 KB 0% 1.06 KB
packages/workbox-cache-expiration/build/workbox-cache-expiration.prod.js 3.41 KB 3.41 KB 0% 1.26 KB
packages/workbox-cacheable-response/build/workbox-cacheable-response.prod.js 594 B 594 B 0% 350 B
packages/workbox-cli/build/app.js 6.50 KB 6.50 KB 0% 2.16 KB
packages/workbox-cli/build/bin.js 2.32 KB 2.32 KB 0% 1.03 KB
packages/workbox-core/build/workbox-core.prod.js 6.48 KB 6.48 KB 0% 2.59 KB
packages/workbox-google-analytics/build/workbox-google-analytics.prod.js 2.13 KB 2.13 KB 0% 1.05 KB
packages/workbox-precaching/build/workbox-precaching.prod.js 5.26 KB 5.65 KB +8% 2.15 KB
packages/workbox-range-requests/build/workbox-range-requests.prod.js 1.64 KB 1.64 KB 0% 807 B
packages/workbox-routing/build/workbox-routing.prod.js 2.77 KB 2.77 KB 0% 1.25 KB
packages/workbox-strategies/build/workbox-strategies.prod.js 3.38 KB 3.38 KB 0% 1.04 KB
packages/workbox-sw/build/workbox-sw.js 1.46 KB 1.46 KB 0% 793 B
packages/workbox-webpack-plugin/build/generate-sw.js 7.38 KB 7.38 KB 0% 2.44 KB
packages/workbox-webpack-plugin/build/index.js 742 B 742 B 0% 470 B
packages/workbox-webpack-plugin/build/inject-manifest.js 8.96 KB 8.96 KB 0% 2.92 KB

Workbox Aggregate Size Plugin

☠️ WARNING ☠️

We are using 158% of our max size budget.

Total Size: 23.19KB
Percentage of Size Used: 158%

Gzipped: 9.22KB

@jeffposnick
Copy link
Contributor

LGTM.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants