Precaching Best Practices
-
Hi,
There is something wrong in my app with the precaching setup.
If I set precaching route as follows, with no versioning, the app won’t work offline because it looks for the versioned script when running offline.
wp_register_service_worker_precaching_route('/wp-content/themes/astra-child/style.css',$args);
Then I have to set precaching route as follows for the app to work properly offline:
wp_register_service_worker_precaching_route('/wp-content/themes/astra-child/style.css?ver=1.0.0',$args);
So, I have to include a version for every script file (.js,.css) precached. This means that I will have to edit child theme’s functions.php every time there is an update in any of these versioned scripts.
Please advise on how to implement precaching best practices.
Thanks in advance for your help.
-
Yes, this is a bit tricky.
Best thing to do would be to not manually add the version to the URL being precached and instead let WordPress generate it for you.
Here is a standalone plugin you can use: https://gist.github.com/westonruter/caa6e08b8d1f70cd3ddab1064d7d1bc2
With that plugin code running, and assuming your theme’s stylesheet has a registered handle of
astra-child-style
, then you can flag it for precaching by doing the following:wp_style_add_data( 'astra-child-style', 'precache', true )
This should be called right after you register the stylesheet.
There is an integration‘ bundled with the plugin which does this as well, but it is not enabled by default: https://github.com/xwp/pwa-wp/blob/0.3.0/integrations/class-wp-service-worker-styles-integration.php
But the integration needs more work, I think. Granted, the PWA plugin overall is still a work in progress. Work is needed to get a sense of the best patterns for theme/plugin authors to provide a good developer experience. We don’t want to add too many abstractions early and instead focus on the fundamental building blocks. This is why integrations are not enabled by default, and they are more experimental than the rest of the plugin.
Hi Weston,
Thank you for your immediate reply and the info about these two options for the precaching setup. I will take a look at these two strategies immediately and select the most appropriate one for my project.
Plugin documentation does not tell much about precaching arguments needed when using
wp_register_service_worker_precaching_route()
, it just mentions the ‘revision’ argument as being optional.What if I want to set a file cache expiration for precaching route as follows?
$args = array( 'strategy' => WP_Service_Worker_Caching_Routes::STRATEGY_CACHE_FIRST, 'cacheName' => 'precaching', 'plugins' => array( 'expiration' => array( 'maxEntries' => 50, 'maxAgeSeconds' => 60 * 60 * 24 * 180 ), ), );
Are these arguments unnecessary or invalid when using the precaching function?
Thanks in advance for your help.
Those arguments do not apply to precaching. They only apply to runtime caching.
If you want to invalidate a precached file, you just modify the revision. So here you would just increase the version for the stylesheet.
Hi Weston,
Thank you for the clarification regarding precaching arguments.
Your plugin is great and I want to stick to it as much as possible. Our app is almost ready and we have not installed any other additional plugin yet. In fact, our app is passing the Lighthouse PWA validation.
Attending your suggestion, we have enabled the following two experimental integrations:
add_theme_support( 'service_worker', array( 'wp-site-icon' => false, 'wp-custom-logo' => false, 'wp-custom-header' => false, 'wp-custom-background' => false, 'wp-scripts' => true, 'wp-styles' => true, 'wp-fonts' => false, ) );
The caching problem persits after enabling these two integrations. App is working offline at the time of installation but not after a few hours of being installed. 4 of the 18 scripts files (css/js) are not being served offline. These 4 scripts belong to the Astra parent theme assets. The rest of the app files are being served offline (pages/images/css/js).
I guess these plugin integrations are quite useful for my project but I simply don’t know what they are intended for.
We need a solution for the precaching problem and we definitely want to give these integrations a try without using any other third-party plugin.
Thanks in advance for your advise on this topic.
- This reply was modified 5 years, 2 months ago by jimador.
Yes, I don’t necessarily recommend using the experimental integrations. You can instead copy the code I referenced above in the Gist I wrote: https://gist.github.com/westonruter/caa6e08b8d1f70cd3ddab1064d7d1bc2
Hi Weston,
Thank you for writing the PWA Precache Styles plugin.
I disabled the experimental integrations and installed and activated this new plugin already. I applied the following changes in the child theme’s functions.php script:
function child_enqueue_styles() { wp_enqueue_style( 'astra-child-theme-css', get_stylesheet_directory_uri() . '/style.css', array('astra-theme-css'), CHILD_THEME_ASTRA_CHILD_VERSION, 'all' ); wp_style_add_data( 'astra-theme-css', 'precache', true ); wp_style_add_data( 'astra-child-theme-css', 'precache', true ); }
Then I removed the following two lines from functions.php script:
wp_register_service_worker_precaching_route('/wp-content/themes/astra-child/style.css'); wp_register_service_worker_precaching_route('/wp-content/themes/astra/assets/css/minified/style.min.css');
Now these two scripts are being served offline as expected but the following three scripts remain unserved when app is offline:
/wp-content/themes/astra/assets/css/minified/menu-animation.min.css?ver=2.0.1 /wp-content/themes/astra/assets/js/minified/flexibility.min.js?ver=2.0.1 /wp-content/themes/astra/assets/js/minified/style.min.js?ver=2.0.1
Please note that these html script links on app pages do have the version number.
All files are precached with no version number to avoid future maintenance efforts. These three scripts unserved offline are being precached as follows, with no version.
wp_register_service_worker_precaching_route('/wp-content/themes/astra/assets/css/minified/menu-animation.min.css'); wp_register_service_worker_precaching_route('/wp-content/themes/astra/assets/js/minified/flexibility.min.js'); wp_register_service_worker_precaching_route('/wp-content/themes/astra/assets/js/minified/style.min.js');
I want to emphasize that these three scripts are being served offline if you don’t include the version number in the URL but page script links to versioned scripts.
Thanks in advance for your help.
I do not recommend omitting the version from the assets as it will mean difficulty for getting updates pushed out to visitors.
Do you have your site publicly available to test?
Hi Weston,
Thank you for your recommendation.
I found out a weird app behaviour today. My app has a javascript go-back link item [<] in top navigation menu that executes the following code:
javascript: history.go(-1);
. If you browse through the app using this back link item, all precached files are perfectly rendered offline. However, if you visit the same app pages using the respective menu items, the scripts already mentioned (css/js) are not rendered offline.I will ask my client for permission to make the app public.
Thanks again for your kind help.
Navigation via history would be using memory cache not the service worker cache, so that’s why it seems to work at the moment, I believe.
Hi Weston,
Offline rendering of precached assets fails, even when the asset has been precached with the version number as follows:
wp_register_service_worker_precaching_route('/wp-content/themes/astra/assets/css/minified/menu-animation.min.css?ver=2.0.1&__WB_REVISION__=2.0.1');
Thank you in advance for your help.
@jimador Instead of precaching specific assets, please rather try use runtime caching. Use the code in this plugin, for example: https://gist.github.com/westonruter/1a63d052beb579842461f6ad837715fb
Runtime caching is generally better than precaching because:
- The service worker doesn’t have to re-install to get an updated asset.
- A network-first caching strategy can be used which makes it easier to see changes (as opposed to precache which is always cache-first).
- You only cache the files the user is actually loading.
Note that you’ll need to navigate at least to one additional page after landing on a site so that the assets will be added to the cache. This requirement will be eliminated with https://github.com/xwp/pwa-wp/issues/180
Hi Weston,
My app must have a basic functionality when first installed, even if the user does not browse through its pages after installation. As far as I know, this is what precaching is for.
We know that the assets in question are there in the cache because the Browser can in fact retrive them offline if accessed directly using the respective URL, but the service worker for some reason won’t serve them. We will be testing plugin precaching the following days before going with the Runtime caching.
I am aware that you shouldn’t preacache too many assets, but I would like to know if your PWA plugin has any preset limit.
Thanks again for your help.
- This reply was modified 5 years, 2 months ago by jimador.
There is no preset limit to the number of precached files imposed by the plugin (which uses Workbox).
In regards to getting precaching to work, I’m able to successfully access a
style.css
file offline when using this plugin referenced above: https://gist.github.com/westonruter/caa6e08b8d1f70cd3ddab1064d7d1bc2When active with Twenty Nineteen, I just add this line:
wp_style_add_data( 'twentynineteen-style', 'precache', true );
In the console (with
WP_DEBUG
enabled) I see:workbox Precaching 3 files.
View newly precached URLs.
https://wordpressdev.lndo.site/core-dev/src/wp-content/themes/twentynineteen/style.css?ver=1.4&__WB_REVISION__=1.4
…I can go offline and still access:
https://wordpressdev.lndo.site/core-dev/src/wp-content/themes/twentynineteen/style.css?ver=1.4
In the generated service worker, I can see:
// IIFE is used for lexical scoping instead of just a braces block due to bug in Safari. ( () => { wp.serviceWorker.precaching.precache( [ { "url": "https://wordpressdev.lndo.site/core-dev/src/wp-content/themes/twentynineteen/style.css?ver=1.4", "revision": "1.4" } // ... ] );
And I can see the
style.css
file in thewp-/-precache-front-v1
cache under Cache Storage in Chrome DevTools. So it seems to be working just fine.Hi Weston,
I installed this PWA Precache Styles plugin three days ago. All the tests we have performed since that date have this plugin enabled. The results are exactly as you just mentioned. Everything works fine at the time of app installation. We go offline immediately after installation and everything works perfectly, all files and scripts are served offline. The problem comes out one or two days after app installation, when some of the precached files stop being served offline.
As I mentioned before, we added the following two lines of code:
wp_style_add_data( 'astra-theme-css', 'precache', true ); wp_style_add_data( 'astra-child-theme-css', 'precache', true );
This code gets the following two scripts precached:
/wp-content/themes/astra/assets/css/minified/style.min.css?ver=2.0.1&__WB_REVISION__=2.0.1 /wp-content/themes/astra-child/style.css?ver=1.0.0&__WB_REVISION__=1.0.0
But the following scripts are not being precached automatically:
/wp-content/themes/astra/assets/css/minified/menu-animation.min.css?ver=2.0.1 /wp-content/themes/astra/assets/js/minified/flexibility.min.js?ver=2.0.1 /wp-content/themes/astra/assets/js/minified/style.min.js?ver=2.0.1
Then we have to include them in the precaching list:
wp_register_service_worker_precaching_route('/wp-content/themes/astra/assets/css/minified/menu-animation.min.css?ver=2.0.1'); wp_register_service_worker_precaching_route('/wp-content/themes/astra/assets/js/minified/flexibility.min.js?ver=2.0.1'); wp_register_service_worker_precaching_route('/wp-content/themes/astra/assets/js/minified/style.min.js?ver=2.0.1');
We tested precaching with no versioning at all with no success. Then we tested precaching with versioning as
?ver=2.0.1&__WB_REVISION__=2.0.1
and it didn’t work either. Now we are testing precaching with just?ver=2.0.1
to see if it works.Thanks again for your professional help.
- The topic ‘Precaching Best Practices’ is closed to new replies.