I am trying to add PWA offline support to a Babylon app, to run it without internet on a Pico 4 VR glass set. At first this seemed to work fine, but then I discovered that it did not really cache all the necessary resources.
When wrting the ServiceWorker sw.js one apparently has to specify a list of all files that should be cached. I can do this for my app, but how can I find out all the necessary resources which Babylon needs and supposedly also all the Babylon internel .js files? Is there such a list, which could be used?
Or is there a better way around to automatically cache all the needed resources for offline use?
I did find this post:
but I could not really understand the way the caching is done there and how it knows about which files and assets to cache.
It’s easiest when you are using something like webpack, but the general idea is that you use tooling to generate a file manifest that knows the dependencies (essentially, your node_modules) of your code via import or require statements.
ServiceBox is the node package I used to make Space-Truckers: The Video Game that formed the basis for my book, and I found it super simple to get working.
The caching is done by specifying a pre-fetch list of URL’s as part of the PWA/SW registration scripts. Subsequent requests for the same URL will be intercepted and return the cached version from the SW.
Yes. I works. However, you need to load the installed app at least once before you can go offline.
An important ingredient is: engine.enableOfflineSupport = true;
somewhere at the beginning of createScreen().
If you have a typo in one of the filenames to preload, the whole cache.addAll() call fails without telling you which of the files it had problems with. So you need to test them individually to find your typo.
This is why I’d recommend tooling to generate the list of files to preload - one less thing to worry about or do when you change assets!
If you’re not using something like ServiceBox and/or WebPack, one simple way to accomplish this could be to write a shell script that searches through your source code to find strings representing URLs, then spits out a list of those into a file that you can then curate and use with your manifest. It’s not a complete solution, but it’s enough that you won’t have to worry about typos at least
The service worker that I linked above seems to have a pretty smart system even using a cache database. But on the second day it turned out the the PWA that was perfectly running on day one must have dropped its cache on day 2 and it did not work any more on the pico 4 without reconnecting. Not sure how to track down what is the problem.
The problem seems to be that I did not explicitely cache the babylon core parts. If I remote-debug the Pico 4, after a day or two it has forgotten the babylon.js core parts:
Failed to load resource: net::ERR_INTERNET_DISCONNECTED
babylon.js:1 Failed to load resource: net::ERR_INTERNET_DISCONNECTED
babylonjs.proceduralTextures.min.js:1 Failed to load resource: net::ERR_INTERNET_DISCONNECTED
babylonjs.materials.min.js:1 Failed to load resource: net::ERR_INTERNET_DISCONNECTED
babylonjs.postProcess.min.js:1 Failed to load resource: net::ERR_INTERNET_DISCONNECTED
babylonjs.loaders.js:1 Failed to load resource: net::ERR_INTERNET_DISCONNECTED
babylon.gui.min.js:1 Failed to load resource: net::ERR_INTERNET_DISCONNECTED
Previously I tried putting the network locations on the list of files to cache, but this also did not seem to work right. Do I need to download them individually and make my app point to local copies? But then where can I find such a list of dependencies, as it seems that Babylon.js might itself import a number of things (WebGL?). I see that you link seems about this, but I have to admit, that I understand very little of it. (What is a “CDN”? What is “PHP”?)
All of those files are available on our CDN, which can be used as the URL for the caching mechanism.
Personally, I am a bit confused as to what exactly is the problem right now, but this might be that I am missing the code/project or an example of what youa re doing now and what exactly isn’t working. But I will be happy to provide any help, if I can
If you’re looking for something more in-depth, there are chapters in my book which explicitly cover the topics of building, packaging, and deploying your BJS web application, including step by step on making a PWA.
Somehow they show up in the “precache” tab (not so in the “runtime” cache), but with a content legth of zero. I guess the browser anyway caches them separately so it works for a day even with out internet connection, but the next day, it fails.
Interestingly the Axaj one seems to be fine (see last line).
I will try downloading these files by hand now and see if it works then.
Thanks for the hints. In the above the non-local network links were just included in the list of files to cache.
The server serving the app is github.io. No idea how to configure this.
I tried with the downloaded babylon.js (etc.) files and then get (after a day) the Warnings, that it cannot find the babylon.js.map file and similarly “.map” files for all others.
And this error:
Search in the code of your own app for fetch commands, which use http: or https: addresses. Download those assets (right-click in chrome) and place them in your local assets folder and change the fetch command to the local assets path.
put the line engine.enableOfflineSupport = true; as the first entry in your create_scene() function. This enables an extra assets caching mechanism of Babylon.
Replace your https://cdn.babylonjs/... entries (<script src="...">) in your index.html file with the local versions <script src="babylon/...">
‘babylon/babylon.js’, ‘babylon/babylon.js.map’, ‘babylon/dat.gui.min.js’, ‘babylon/earcut.min.js’, ‘babylon/babylonjs.materials.min.js’, ‘babylon/babylonjs.materials.min.js.map’, ‘babylon/babylonjs.proceduralTextures.min.js’, ‘babylon/babylonjs.proceduralTextures.min.js.map’,
‘babylon/babylonjs.postProcess.min.js’, ‘babylon/babylonjs.postProcess.min.js.map’, ‘babylon/babylonjs.loaders.js’, ‘babylon/babylonjs.loaders.js.map’, ‘babylon/babylon.gui.min.js’, ‘babylon/babylon.gui.min.js.map’,
Be ware that a type here is critical and will cause an error in the whole caching process. See last point below on how to do checks.
Increase the version number in your serviceworker file by one, e.g. const PRECACHE = 'precache-v002';.
Deploy your app.
Test your app by installing the PWA, installing from the deployed source, running it once, turning off the internet connection, making sure that you can still start without internet, and waiting for at least one night and try to then start it again without having turned on the internet connection in the mean time. You can see if everything was cached OK by using ... -> Open in Chrome and in the chrome menu More Tools -> Developer Tools -> Application -> Chache Storage -> precache_vxxx with the current number in xxx (002 in the example above) and the runtime entry.