workbox icon indicating copy to clipboard operation
workbox copied to clipboard

[discussion] Resources for Multi Page Applications (MPA's)

Open thepassle opened this issue 4 years ago • 7 comments
trafficstars

Hey gang,

This issue is more of a starting point for a discussion rather than an issue or feature request for the workbox library — I hope that's okay. (Although it may evolve into a feature request I suppose 😄 )

At open-wc and modern web, we build our documentation site with a meta-framework built on top of 11ty and rollup. Our documentation site is mainly HTML, with a light sprinkle of JS. We would very much like our documentation to be available offline for our users, so users can still consume our documentation if they dont have a network connection.

The current implementation we have for this is a simple skipWaiting/clientsClaim pattern. The 'problem' we face here is that our project has grown quite rapidly over the past few years (so we have lots of documentation/pages), and we make updates to our docs quite frequently. This means that whenever we update the docs, our users now have to redownload our entire docs site again essentially, if we want them to be able to use our docs while offline. While in terms of UX, the user shouldnt even really notice this happening at all, but it doesnt seem very friendly on their data consumage, and simply feels somewhat 'off'.

image

To illustrate the issue described above, it takes a solid 25(!) seconds to update the cache

When searching the web for resources about PWA's, many of them seem to assume that you're making a SPA with the app shell pattern, and solely revolve around that pattern. There are also a couple more 'experimental' resources wrt 'streaming service workers', but I find it genuinely hard to find any solid alternative patterns for MPA projects, and I wonder if Workbox, as the leading service worker library, could(/or would be interested) in having some kind of role in this; perhaps in the form of documentation of different patterns, and perhaps maybe even some default plugins that could help with this.

We'd love to see if any kind of discussion around MPA projects could take place, as well as participate and help move those forward. Happy to hear your thoughts on this and see if we can make something happen in this space 🙂

thepassle avatar Apr 29 '21 07:04 thepassle

To highlight another very confusing situation for our users:

  1. User visits open-wc.org
  2. User has a valid cache and it works offline
  3. We publish a new blog post as open-wc.org/blog/my-new-post/
  4. We share that link on twitter and people click it
  5. New Users see the blog post
  6. Existing users see a 404 page until the page reloads with the service worker (which can take up to 25 seconds 🤦‍♂️)

I am thinking that something like this might work conceptually - but how to implement it?

  1. pages loads
  2. service worker serves cache
  3. update cache only for the current URL (https://domain.com/foo/bar.html) and all its resources (I'm not really sure how possible that is)
  4. reload the page with the new service worker (users sees new page content now)
  5. update the cache for all other new resources in the background

daKmoR avatar Apr 29 '21 07:04 daKmoR

Hey @daKmoR and @thepassle—thanks for bringing this up. I've got a lot of thoughts on the matter 😄

First off, I agree that the current setup you have is not ideal—I don't think (pre)caching full HTML documents is a good pattern to follow, and whenever possible, recommend caching partial HTML templates and content separately. Unfortunately, many of these patterns require adopting a specific architecture from day one, and are hard to retrofit on existing sites.

Here are some previous attempts at sharing patterns, some of which match what you're trying to do:

  • Beyond SPAs: alternative architectures for your PWA: This talk covers a "generic" way of sharing server-side and service worker-side routing and templating logic, and might be what you referred to as the guidance around streaming responses. (Since originally giving this talk, the underlying sample app has been upgraded to use Lit for its templating.) I really like this architecture, and feel like you could swap out the Stack Overflow API with any other "content" API under the hood to produce equivalent versions of the same general site. This architecture would be really difficult to retrofit on an existing site, though.

  • I've blogged (one, two, three) and given some talks about my https://jeffy.info/ static site + service worker setup, which used to rely on Jekyll and now uses 11ty. This is actually a little easier to retrofit on existing sites if you're using Nunjucks-compatible templating, but there's no ready-to-use starter kit for this specific architecture.

  • We did see the need for something that did provide a good starting point for fresh projects built on 11ty, and members of the Workbox team contributed ideas to the Chrome OS team's static site scaffold, which was used to create https://chromeos.dev/. This is what I'd point folks towards if they were starting a new project, wanted to use 11ty, and wanted it to be a PWA with a reasonable caching policy, but it again is not something that could be retrofitted on an existing project.

That's a rough survey of what's out there right now.

The running theme is that coming up with a "good" service worker caching and serving strategy requires a deep understanding of site architecture, which in turn means there is no one-size-fits-all solution, and retrofitting a service worker after the fact can lead to subpar experiences. (Say what you will about SPAs/App Shells, but it's a generic architectural pattern with an caching model that lends itself well to service workers.) I think that advancing this space requires working on a framework-by-framework basis to figure out how to provide starting points, along the lines of static-site-scaffold, that folks could opt into if they want to take advantage of service worker caching.

If the architectural constraints and patterns laid out in that material linked to above make sense, and you're in a position to help provide good starting points for any existing frameworks/site generators, I think that's one way forward.

jeffposnick avatar Apr 29 '21 13:04 jeffposnick

Thank you for your hints 🤗

It kicked our buts to take/offer more control over how the service worker system should be for our static sites.

We are now planning to use a very simple setup using workbox https://github.com/modernweb-dev/rocket/blob/main/packages/cli/preset/_assets/service-worker.js for all of them.

Right now we test it on base system site.

It's a starting point towards what you blogged about and it sort of follows the talk Service Workers For The Rest Of Us by Philip Walton.

It's amazing how simple that is to setup using workbox - thanks for offering that 🙇‍♂️

In the end, we are hoping to be able to offer something as outlined in your third blog post by default.

But I think we are having a good/better starting point now.

Maybe you can briefly glance over the service-worker.js and the way we register it.

Just so we are not doing anything super stupid 😅

PS: the documentation site for how we are now offering service workers (while recommending workbox) you can find here - if you are curious 🤗 PPS: exiting opportunities here 🤗

daKmoR avatar May 04 '21 06:05 daKmoR

Hey @daKmoR—glad the resources were useful.

The main concern that I have with the approach in that service worker is what I describe here:

Don't cache full HTML I recommend against storing complete HTML documents in your cache. For one thing, it's a waste of space. If your web app uses the same basic HTML structure for each of its pages, you'll end up storing copies of the same markup again and again. More importantly, if you deploy a change to your site's shared HTML structure, every one of those previously cached pages is still stuck with your old layout. Imagine the frustration of a returning visitor seeing a mix of old and new pages.

I do agree that the proposed service worker logic it makes more sense that precaching dozens of HTML document and then re-downloading them all each time one thing changes. As long as you understand the implication, and are moving towards a model where you cache content and layout separately, I think you're good for now.

jeffposnick avatar May 04 '21 13:05 jeffposnick

awesome thank you 🤗

yes I see this as a starting point that we can build upon 👍 it's already improving the current situation - but yes it's not (yet) the final solution

more iterations will be needed - we now have at least a plan and a it seems feasible way of implementing it 🤗

daKmoR avatar May 04 '21 22:05 daKmoR

I'm interested to hear feedback on https://jeffy.info/2021/07/17/sw-rendering.html as a possible approach for you all to adopt.

jeffposnick avatar Jul 19 '21 12:07 jeffposnick

I do have monolithic architecture application which serve multiple domains, and need a guide to generate multiple service-worker with webpack-workbox-plugins How can I differentiate the generated precache

xicond avatar Jun 13 '22 04:06 xicond