Appcache and dynamic-import incompatible

It looks like appcache and dynamic-import are incompatible.

My guess is (I’ll look into it further if I get a chance), the dynamic import feature stores everything in indexedDB, and the app cache manifest forces the browser to put dynamic modules into the browser app cache (which makes me think these modules are getting downloaded twice). And then when offline, dynamic imports can’t load from app cache.

Anyone know if there is a way to get these to work together?

I’m using appcache instead of web workers because even though it’s deprecated, every browser I need to support is supported - whereas less than half the browsers I need to support have web workers (no Edge/IE or Safari).

I’ve disabled dynamic imports on the part of the app I want cached for a workaround - but I’m still concerned about a possible double download penalty.

1 Like

Is there a way to get dynamic-import to load modules from the app cache, instead of indexedDB?

This sounds like a bug. Have you tried reporting it in the Meteor repo?

I have not - I wasn’t sure the appcache package is still a priority. I actually think a more specific offline caching effort would be nice. There are a couple of areas that we need, and a couple of technologies to support.

Things needed:

  1. Offline cached application bundle and CSS (the initial JS bundle). Appcache now, Web Workers in the future.
  2. Offline cached additional modules. These are already cached for offline in indexedDB - but we probably still need the prefetch case worked out. Right now appcache manifest sends those out, but dynamic-imports doesn’t use them.
  3. An arbitrary offline API for additional assets. For example, I have some routes where I’d like to stuff some images and fonts in an offline cache container. (Maybe I can just use Ground:DB for this, or go lower level and use localforage, which Ground:DB uses behind the scenes)
  4. Offline Data - this can be done with Ground:DB if using minimongo. There are also Redux solutions, and I haven’t looked, but I bet there is already something for Apollo.

Tech to support (and deprecate):

  1. Appcache (deprecated) - this is all static manifest based, and is deprecated due to flaws with it’s design and the various implementations. It should probably only be used for the initial bundle, and not for additional packages, due to the size limitation on iOS Safari (I have a real hard time getting my bundle size small enough to fit inside the 5MB limit on some apps). In Meteor’s current implementation, additional modules are set separately, but dynamic-imports doesn’t seem to load from there. So the bug is either in dynamic-imports, where is should check the appcache before fetching over DDP, or it’s in appcache, where those additional modules should not be added to the manifest at all. NOTE: This is based on deprecated, though still widely supported tech. It will be removed from browsers eventually.
  2. Web Workers - there is a more open ended offline cache system in Web Workers which may need to be supported in the future, for any robust offline support. If appcache is removed, it may be necessary to use this in it’s place for the initial bundle/css files. It is not yet widely supported (only Chrome and Firefox currently support it), and maybe it’s support is uncertain? One nice thing about it is that it can support arbitrary caching at runtime - no need for static manifests. An arbitrary offline-cache API can also be built with indexedDB though as mentioned above - so there’s not a real need to use Web Workers (with messages and the Cache API).

Sorry for the data dump - just trying to get all my notes and thoughts in one place.

Anyway, for Meteor a robust offline story could be a great top level feature. Even better if it has some kind of general purpose syncing system with conflict resolution.

This is no longer true. I wrote some pull requests and they got merged!

One pr stops appcache from publishing files the system will never use, and the other (in dynamic-imports) prefetches every module on page load if appcache is enabled.

I think they’ll ship in 1.6.1.