fresh icon indicating copy to clipboard operation
fresh copied to clipboard

Fresh service worker

Open argyleink opened this issue 2 years ago • 3 comments

Service workers could save a ton of server load. Fortunately, Fresh has all the information needed to automatically generate a meaningful service worker: routes, assets, bundles…

I'm here to request that Fresh integrated service workers out of the box 😅

SW could cache…

  • same domain html (offline articles)
  • images
  • everything in static/

Seems like there's an opportunity here to both makes Fresh projects faster and reduce server and cdn loads.

argyleink avatar Jan 12 '23 06:01 argyleink

I tried creating a Fresh plugin the other day to support serving a Fresh app offline via a service worker. I got blocked by service workers not supporting 2 things:

  1. top-level await
  2. dynamic import()

I think top-level await can be worked around by wrapping code inside of an asynchronous IIFE but I couldn't find a way around the dynamic import(). Shimport might work but I started digging into why a dynamic import() was needed and I realized it was from denoflate pulled in by esbuild. Running esbuild using WASM inside a service worker might have some use cases but I think caching the precompiled JavaScript files to hydrate islands would typically be better (fewer resources needed on the client in the service worker plus less CPU usage).

After realizing that I wanted to experiment with what a solution might look like so I rolled something more basic than Fresh but works offline: https://github.com/mfulton26/offline-mpa/. It is server-side rendered but instead of islands I'm doing full page hydration for simplicity but the idea should be the same. Almost all the code is reused between the server and the service worker. The main differences are that the server bundles JS on-demand while the service worker pre-downloads those bundles, caches them, and then serves those from the cache.

Can a similar pattern to what I was able to get working in my offline-mpa be used here in Fresh? I think the main blocker at the moment is that ServerContext in Fresh depends on the Bundler but if that can be injected when run on the server and be substituted with a cache loading/serving solution for a service worker then offline support (via a plugin?) can become a reality for Fresh!

mfulton26 avatar May 19 '23 14:05 mfulton26

The new ahead-of-time builds should be usable as a manifest for a service worker. I feel like Fresh is already in a pretty close state to supporting offline apps. I think if any esbuild loading code were made conditional (e.g. via dynamic import) then bundling bundle most of the app as a service worker should work well as most code is "universal" (i.e. can be run in Deno and browser contexts).

Lack of official offline support is the main blocker for my team and me to using Fresh at work. @marvinhagemeister, do you think offline support as an official plugin aligns with Fresh's vision/scope/etc.? How might we get such prioritized? I can try doing a PR myself but I'm not confident in my familiarity with the codebase, etc.

mfulton26 avatar Oct 02 '23 13:10 mfulton26

So far the interest in offline support is very low compared to all the other features. That's why it's not on the roadmap. I'm definitely open to accepting PRs if folks want to put in the work for that.

marvinhagemeister avatar Oct 18 '23 13:10 marvinhagemeister