Context
A training app is used in the worst conditions a web app can face: phone in hand, screen dimming, network absent or unreliable, and the user unable to stop and troubleshoot. A page that needs a connection to open is a page that fails at the moment it is needed. The engineering question was whether a browser application could behave like an installed one under those conditions, without a framework and without a build step.
My role
Sole developer. Built the routine engine, the timing system, the persistence layer, and the offline infrastructure.
Process
- Wrote a service worker with two deliberately different caching strategies: application files precached at install for guaranteed offline availability, and remote fonts in a separate runtime cache that falls back to whatever is already stored. Navigation requests fall back to the cached shell, so the app opens with no network at all.
- Versioned the cache and deleted every non-current cache on activation, so a stale asset from a previous release cannot survive an update.
- Held the screen awake through the Screen Wake Lock API during a session, and re-acquired the lock when the app returned to the foreground, since a lock is silently dropped when the page is backgrounded.
- Synthesized every audio cue through the Web Audio API rather than shipping sound files, which keeps the offline payload small and gives precise control over cue timing.
- Built the session as a generated structure rather than a fixed list, so a single scaling parameter halves every repetition and interval throughout without a second code path to maintain.
- Persisted progress in local storage with plain-text export and re-import, so a reinstall does not erase the user history.
- Handled real phones rather than an idealized one: safe-area insets for notched displays, vibration where supported, and a reduced-motion query honored throughout.