A personal gripe with progressive web apps: they cache the website!!
A lot of people have requested that I make a progressive web app for https://plaintextsports.com. I've looked into it, but it fundamentally doesn't work, because it caches the home page. My website doesn't load any data via JavaScript; it just relies on the HTML page updating every 30 seconds, so when the home page is cached, the website just stops working.
I don't want this service worker nonsense. In most cases offline access isn't useful; people want the live scores. (It'd be moderately useful for viewing schedules offline, but I think most people use it for live scores.) I just want the website to show up as its own app in the app switcher, and basically nothing else to change: I still want the swipe-to-go-back gesture to still work. I still want the address bar with the manual refresh button. But I can't do that.
It's frustrating that they've provided a way to make a certain style of websites into first-class apps, but it doesn't work for the most basic websites!!
Side note: this is partially a the-best-way-to-get-a-question-answered-on-the-internet-is-to-say-something-wrong post. If there's a way to make it a PWA and not have all the pages heavily cached, please let me know! I would love to be wrong on this. (Unfortunately my noprocast just triggered though, so I won't be able to edit this post or respond for the next three hours.)
Your service worker dictates what the browser should cache. You could cache static assets only and let the browser hit the server for document requests.
As for the refresh button, mobile users are now used to pull to refresh so you might not need an actual refresh button.
As an aside, I dig the design! It reminds of teletext haha
It has been awhile since I've personally tried creating a PWA, but I don't think iOS does any form of extra caching for PWAs. I think it is more likely that you copy/pasted an example service worker that was caching things you didn't expect it to cache. Some info about PWA caching here[0].
That page also talks about "What to Cache" here[1], and it specifically suggests that most apps will want to cache the main page's HTML.
Now that iOS will supports push notifications in PWAs, I definitely plan to try out the developer experience again soon.
> I still want the address bar with the manual refresh button. But I can't do that.
Yeah, I mean... you're meant to provide an app-like experience if you're doing a PWA. You could certainly build your own stylized, floating bar that only shows up in PWA mode, or think about new ways to let users control the way the page updates. Alternatively, you could just automatically refresh the page with a setTimeout?
I'm not sure how much you want to invest in experimenting with the technical foundations of your app, but I wrote out a few ideas that occur to me:
- Your Cache-Control header is kind of weird. `max-age=15`. I would expect to at least see a `public` or `private` directive in there to specify how this data is supposed to be handled by intermediate proxies. Something like your website is a prime candidate for caching in a CDN layer, and I think you generally want to specify `public` for CDNs to do anything useful. Maybe they default to `public`? I've honestly never felt the need to try. Beyond the `public` / `private` discussion, `stale-if-error` could be useful so the CDN could serve the most recent info even if your application is having a brief outage. If you're not using a CDN... probably something worth checking into.
- As cool as just serving self-contained HTML document is, your page is still transferring 6 kilobytes each time it refreshes. If the goal is to lower that as much as possible, I would start by pointing out that you don't need to send your JavaScript snippet every single time the page loads. It looks to be several thousand bytes uncompressed, although I'm not sure exactly how much it is affecting your compressed payload size. You could separate that into an aggressively cached JavaScript file that is served separately from the HTML. (As usual, best practice is to have a file hash in the name of the javascript file, that way the cache time can be infinite. If the javascript needs to be updated, the hash would change, so the browser wouldn't have that cached, and would fetch the new file immediately, as soon as the refreshed HTML file requests it.)
- But then after that... the next logical step is to render the actual score interface client-side, since the score data is significantly smaller than the HTML needed to render the score data. This would also allow you to handle refreshing more elegantly from the client by just fetching the data route that returns a JSON blob, and re-rendering the HTML. At this point, the HTML representing the empty app shell could be cached too, but it would probably be best to limit the cache duration depending on your preferences. The right value for HTML caching would likely be somewhere between a few minutes and a few days. Now, opening the app would load the locally cached HTML and JavaScript, and then the JavaScript would just fetch the tiny blob containing only the scores and nothing else. Of course, you could cache this information locally so that when the PWA is opened, the user can always see the last information (and when it was fetched) even if they don't have an internet connection, while the PWA can continue trying to fetch the updated scores.
- Taking this to the extreme, the maximally efficient design for something like this would probably involve an SSE (server sent events) endpoint that the client would subscribe to. Whenever the scores actually do change, the server could push that straight down to the client. This would reduce the latency from your current 30 second target, and it would also use even less data since people aren't refreshing and receiving the same stale data multiple times. (I will note that a good implementation of this would still send a tiny ping from server to client every minute or two just to ensure the connection doesn't get silently dropped by any weirdly configured firewalls along the way.)
- If you were really going all-in on features, well... this whole HN discussion is highly focused on push notifications, so you could always let people subscribe to specific teams, and send them a push notification when scores change for those teams.
A lot of people have requested that I make a progressive web app for https://plaintextsports.com. I've looked into it, but it fundamentally doesn't work, because it caches the home page. My website doesn't load any data via JavaScript; it just relies on the HTML page updating every 30 seconds, so when the home page is cached, the website just stops working.
I don't want this service worker nonsense. In most cases offline access isn't useful; people want the live scores. (It'd be moderately useful for viewing schedules offline, but I think most people use it for live scores.) I just want the website to show up as its own app in the app switcher, and basically nothing else to change: I still want the swipe-to-go-back gesture to still work. I still want the address bar with the manual refresh button. But I can't do that.
It's frustrating that they've provided a way to make a certain style of websites into first-class apps, but it doesn't work for the most basic websites!!
Side note: this is partially a the-best-way-to-get-a-question-answered-on-the-internet-is-to-say-something-wrong post. If there's a way to make it a PWA and not have all the pages heavily cached, please let me know! I would love to be wrong on this. (Unfortunately my noprocast just triggered though, so I won't be able to edit this post or respond for the next three hours.)