-
Notifications
You must be signed in to change notification settings - Fork 275
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
Cache Playground assets to enable offline support #1535
Conversation
Playground can now load from the cache when there is no server. There is still an issue on the first load where some static assets aren't pulled from cache. Other TODOs:
|
packages/php-wasm/web-service-worker/src/initialize-service-worker.ts
Outdated
Show resolved
Hide resolved
On the first sight this looks really good. I'll give this another read during the day – it looks like we're almost there! Thank you @bgrgicak ! ❤️ |
I suspect the issue is because:
This seems fine. I don't think we need to fix anything here, let's just document it somewhere where we'll look for the root cause in the future. Perhaps in the offline testing instructions in the README and here? |
* | ||
* These assets are listed in the `/assets-required-for-offline-mode.json` file | ||
* and contain JavaScript, CSS, and other assets required to load the site without | ||
* making any network requests. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's make it clear we skipped the await
on purpose.
* | ||
* If your build version doesn't change while developing locally check `buildVersionPlugin` for more details on how it's generated. | ||
*/ | ||
cache.cleanup(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The .cleanup()
name make it seem like we're evicting the assets we just requested, how about calling it .removeOutdatedFiles()
and calling if before .cacheOfflineModeAssets()
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also, let's make it clear we've skipped the await
on purpose
return await cache.then((c) => c.match(key, { ignoreSearch: true })); | ||
}; | ||
|
||
shouldCacheUrl = (url: URL) => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is one eager function. It will cache everything we request on the playground.wordpress.net domain, including /demos/index.html
and /client/index.js
. I'm worry about the unintended consequences. Would there be any downside to limiting this to the offline mode assets, PHP builds, and WordPress builds?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why not cache these files? They are small and will load faster after refresh if they are cached.
We would also need to maintain a list similar to the one in listAssetsRequiredForOfflineMode
.
This works really well with the "Offline" checkbox in devtools, but it breaks down as soon as I stop the local PHP server:
I think that's because of the feedback I provided earlier about rethrowing the error. Hm. I wonder what would be a useful thing to do there – we do want to throw if we have the internet and just can't fetch the service worker, but we do not want to throw if we're falling back the offline mode when playground.wordpress.net is down. That is a tough one. Perhaps it's fine to not re-throw the error when we already have a previous version of the service worker in place. What do you think @brandonpayton @bgrgicak ? |
This works really well in my testing @bgrgicak, yay! 🎉 I was able to create a bunch of new Playgrounds, use the browser storage, preserve my site across multiple page loads and keep updating it as I went. Also, it loads so fast now that everything is cached offline. ❤️ I left a few comments, but I don't see any major blockers here. Feel free to merge and address them in a follow-up PR. |
Actually the missing CSS bothered me and I explored a refactor in #1643 – |
I found one more issue and proposed a fix in #1643 |
That's interesting. I didn't have many issues with it while testing, but I experienced that
Similarly, this just worked for me, but not relaying on the browser with |
With #1643 we don't need the comment anymore, but I still added a comment for testing offline. |
A set of bugfixes and enhancements for [PR 1535 – Cache Playground assets to enable offline support](#1535): ### Offline mode after a single page load **Without this PR:** When the service worker is first registered, it does not yet handle the network requests triggered by the page that registered it. Files fetched on the initial Playground load, like `wordpress-static.zip`, are not cached. This means the offline mode won't work yet. You need to do a full page reload, wait for another round of `fetch()`-es, and only then you get cached assets and a functional offline mode. **With this PR:** Service Worker calls `self.clients.claim()` to start controlling the Playground page when the service worker is initially registered. Static assets are cached and offline mode works after the very first page load. ### Backfill static assets before the first paint * If `wordpress-static.zip` is cached, it will be extracted during Playground boot. * If it's not cached, we'll boot and render Playground first, and only then start downloading and extracting that file. ### Other smaller changes * Simplified OfflineModeCache, used class methods (`function myFn(){}` instead of instance methods (`myFn = () => {}`) cc @bgrgicak --------- Co-authored-by: Bero <berislav.grgicak@gmail.com>
I addressed the feedback and merged #1643. We should be ready to merge now. Thanks for your help @adamziel @brandonpayton! |
Motivation for the change, related issues
The promise of Playground is WordPress anywhere.
Playground can run in the browser without a server, but it still requires the internet on every load.
This PR adds caching of Playground assets and ensures they are available when offline.
Implementation details
The Remote Service Worker will start caching when initialized and clean previous versions if they exist.
The WorkerCache class uses browser cache to preload data when the service worker is loaded.
On each unscoped fetch request, it will attempt to load data from the cache by using the
cachedFetch
method.Only URLs that aren't PHP scripts (end with .php) and valid domains will be cached. (see
isValidHostname
for details)Testing Instructions (or ideally a Blueprint)
Note: In Chrome the offline checkbox sometimes stops working. When this happens Playground will load without remote assets and admin styles (including the admin bar) will look broken. If it happens you can confirm it by running
window.navigator.onLine
. To resolve it uncheck and check the Offline checkbox and reload.