Skip to content
All case studies

Case study

Orbit — making a web app feel native on a phone

The product tested well on desktop and felt broken on mobile. Nothing was actually broken, which is why it took a month to work out what was wrong.

Role
Design engineering — interaction, motion and performance
Client
Placeholder Co
Year
2025

Outcomes

310ms → 90ms
Interaction to next paint
+2.4×
Mobile session length
1.1s
Largest contentful paint

Context

Orbit's mobile web experience scored well on every audit we ran and badly in every conversation we had with users. "It feels like a website" was the note, repeated in different words by nine of twelve interviewees. That is not a bug report, and for a while we treated it as unactionable.

Approach

Name the specific feelings

I recorded slow-motion screen captures of Orbit next to three native apps and catalogued each difference. Three patterns explained almost all of it: taps had no immediate acknowledgement, transitions cut rather than moved, and scrolling gave up the position when you came back to a list.

None of those appear in a Lighthouse report.

Acknowledge every touch within one frame

Every interactive surface got a pressed state that fires on pointerdown, before any network work begins. The visual cost is a two-percent scale and an opacity shift; the perceptual cost is zero waiting.

<motion.button
  whileTap={{ scale: 0.97 }}
  transition={{ type: "spring", stiffness: 420, damping: 38 }}
/>

Move things instead of replacing them

List-to-detail navigation became a shared-element transition: the tapped card's image and title travel into the header rather than disappearing and reappearing. The work is one layoutId per element, and it is the single change users mentioned most.

Then fix the actual performance

With the perceptual work done, the real numbers mattered again. Route-level code splitting, a smaller icon strategy and moving the heaviest list to virtualised rendering brought interaction-to-next-paint from 310ms to about 90ms.

Outcome

Mobile sessions got roughly two and a half times longer. In the follow-up round, eleven of twelve users described Orbit as an app without being prompted, which was the actual goal the whole time.

What I would do differently

I would do the perceptual audit first and the performance work second, which is the order we eventually arrived at by accident. Two weeks of early optimisation went into a bundle-size win that no user could feel.

Tagged

  • Motion
  • Performance
  • Mobile
  • React

Next case study

Atlas — a design system three teams actually use

Replacing four diverging component libraries with one typed system, and the governance model that kept it from forking again six months later.