← projects/WHERE slug = 'pabau'
row 2 of 4
Clinic & booking platform
Pabau
Booking software for clinics, where the calendar is the product and every user is looking at a different week.
- slug
- pabau
- kind
- Clinic & booking platform
- year
- 2022 — 2023
- role
- Full-stack developer, product team
- stack
- Next.js, TypeScript, GraphQL, Hasura, Prisma, LESS
- live
- pabau.com ↗
- repo
- NULL
Pabau is practice-management software for clinics and salons. I joined the product team as my first professional role and worked on the booking surfaces: the calendar, the appointment flows, and the GraphQL layer feeding them.
01The problem
A clinic calendar is a dense, high-churn view. It holds many practitioners, many rooms, and many appointments at once, and it changes while you are looking at it. Every member of staff opens it to a different week, filtered differently.
The interface felt slow, and the instinct on a React team is to reach for memoisation. That instinct was wrong here. The components were re-rendering because they were being handed new data on every poll, and they were being handed too much of it — a week view was pulling relations it never displayed.
02What I did
I worked backwards from the render to the query. Where the calendar was making several round trips to compose one view, I collapsed them into a single shaped GraphQL query so the component received exactly the fields it drew and nothing more.
For the parts that had to stay current, I leaned on Hasura's subscriptions rather than interval polling, so a changed appointment pushed one small update instead of the client re-fetching a whole week on a timer.
The React work that remained was then genuinely about rendering: stable keys, splitting the week grid so a single-cell change did not invalidate the row, and keeping derived values out of the render path.
03On reflection
I spent my first weeks optimising renders before I had looked at the network tab. I would now read the payload first on any interface that feels slow. It is a faster diagnosis and it is usually the real answer.