1. Questions
  2. Notes
  3. Mostly incoherent brain dump
  4. Examples
  5. References

Questions

Notes

1. Why

2. How

How do we know if someone is offline? What does offline even mean?

detecting offline is easy - not connected to any network. So no wifi or cable.
But if you are connected to a network, how can you tell if that's the internet
or just a regular net?

navigator.onLine. weird casing.
this can tell you if you are offline (onLine === false) or "not offline" (navigator.onLine === true). Not offline is not necessarily online.

If their router is connected (and real), maybe their ISP is down. Maybe their government censors content. If the ISP is up, mayeb the server of the site is down.
Or at capacity.

So the most reliable way to test it monitor network requests. If a bunch of them
fail, you're probably offline. There's some events you can listen for, you could
use a dedicated polling thing that checks some cheap isUp endpoint, whatever.
Lots of options here.

brief PSA on using .catch correctly. What does .catch mean for fetch
what does it mean for your network lib, or your API wrappers or whatever.
Learn some stuff about errors they are great.
Optimistic approach to errors means expecting them. Plan for them. Do something better than showing unhelpful error.

Assume someone clicks a button, then puts their phone straight back into their pocket. And their pants are made of lead, blocking any signal.

3. What

Plan for the person that has been to site once before. Now they're waiting at an airport,
their flight has been delayed 45 minutes, and they want to read some more.

Step 1. offline.html
Plain page to replace browser default.
Bad news for Chrome users. No longer have a dinosaur game, or the Download When Online button.
Arguably worse experience than browser default.

Step 2. blog.html
So we want something better than static page, let's give people some content.
Fallback to "sorry, can't get that. Would you like to view one of these?"

NB: on pre-emptive loading. Be nice to people's data. TODO: is there a way to detect
network type ala "wifi only download"? Assume small is ok, so you can download text
content and maybe small images. Check what your market is ok with.

We can do better than this still. If we can grab text in the background, and we have
a "people also enjoyed:" links. Use Analytics data, and then pre-emptively fetches content
for those in idle times. So if you come to my blog and visit two pages, auto-download a couple more.

Also the idea of timebox/location-based "predictive" offline. If a user is going
to leave the house and going to the station, sync some things that matter. (opt-in to download all)

This is a common pattern for News, Social Media, anything that is post-oriented is ok.
In SW/Toolbox terms it's called staleWhileRevalidate.
But holy shit please do not use this for time-sensitive data. Especially not if
you are printing relative times on screen. Looking at you PTV app.

Step 3. forms

Adds a lot of potential, and a lot of complexity

The traditional optimistic UI: like/star button
works, but does nothing. Probably not a big deal
The offline optimistic UI: updates live now, really later.
Button queues a request, then actually updates later. Sounds simple... BUT:

Race conditions:

So, so far so simple. Let's try a more complex form.

You know what is worse than filling out forms? Submitting them when you're offline and
getting an error page. Because then you have to fill them out twice.

For any short fields, make autocomplete work. For comment fields, longer notes,
save locally. And save lots. Discarded data is very annoying.

Caveat: don't cache sensitive info. In either formdata or localstorage.
Also applies to caching data that requires auth. If you need to be logged in,
you can encrypt data locally and access with a token, or keep it in sessionStorage
or something else. But be sure that the data doesn't live longer than a session

Step 4. Collaborative Docs

This is where data storage method gets more important. You cannot just store "here's the text"
type values anymore. Think about changes, about conflicts.

NB: sending and handling notifications offline. What happens if someone clicks a
notification while offline? It closes. Does your site work? Can they save it or
get notified again when they can reach it. Can you pre-emptively fetch the page content.
Should you? There are limits, don't be a dick

Step 5. Chat / Games etc

Highly interactive, network-dependent.
This requires a different experience for online vs offline. e.g. Bot that pops up
"you're offline, want me to send that for you later?"
For games, you could drop into training mode. e.g. Chess - "Currently offline, analyze board".
Or "continue against computer". Or training mode.

Scratchpad

Connection continuum: Offline -- Flaky -- Slow -- Fast

Slow and fast are self explanatory. Flaky is an interesting case. What do you think
would happen if every 4th request failed? That is something like what happens
when you have congestion issues. Some requests will take ages, some will fail.

Quality continuum: someone else's error << your error << some content << the actual content

Be Optimistic - Assume devices will reconnect at some point.

Australian internet is rather awful - e.g speedtest screenshot from home
Also: https://twitter.com/SwiftOnSecurity/status/1008561176408707078

show that the default offline experience means abandoning people. You are trusting
the browser to do something

requests are like sheep. Body can only be consumed once, so clone first


whatsapp is good for offline - message just gets sent.
duplicates not a big deal; most people only use one device, so won't accidentally send twice
facebook failed file upload from phone
Self-first sync (for chat). Confirm before auto sending. More hassle than benefit


Does offline last? Why was Guardian crossword shutdown? TODO. Maintenance concerns??

Updating cached data when your service worker updates
note on updating SW version without losing your precious offline pages. You need em.

if you are offline, it should tell you as soon as possssible
if your connection is slow, should offer them the chance to come back later

button for dinosaur game that uses chrome's version
alternatively just use regular js version


Polling

Offline sync
this is the sync problem compounded. Because you are very likely to cause
conflicts somewhere. if you do cause conflicts, cause them in the way that
doesn't again cause future conflicts. Let's quickly look at something that does
a terrible job of this: git. We are editing the following 3 line file. 3 lines,
what could possibly happen.

Jane and Jim are editing a shared file. line 1 has some text added by both
Now both see a conflicts view.
This is designed to be resolved offline.

Choosing a sync model
this is a tricky, tricky thing
but pretty great experience. If we have comments, and I want to copy them to notepad or something, then back to the browser, I should be able to do that
Rather than storing text, store actions/deltas. See redux, quilljs etc for things here.

Online vs Offline conflict resolution. Offline is actually easier, pushes the responsibility
onto them. Online requires lock or something. There are tools to
help with this (firebase or quilljs), but you want to have a conceptual understanding
of what's going on

Offline-only mode

tip: I started this in dropbox note. simple and pretty reliable (NEVER want to lose)
terrible sync support though. If it detects a conflict it just duplicates your files

Getting Buy In: if you need to convince people of business value.

Devs vs users

Offline Examples