Performance rescue
Vue 2 → Vue 3, rewritten from scratch — and slow before it even shipped.
- Client
- Catering enterprise, Germany
- Role
- Senior frontend engineer, de facto tech lead
- Timeline
- [redacted]
- Stack
- Vue 3 · TypeScript · TanStack Query · SignalR · Biome · Feature-based architecture
Context
The team was rewriting a large Vue 2 application in Vue 3. Feature-based architecture, TanStack Query, real-time updates over SignalR. On paper: modern. In the browser: painfully slow.
The problem
- ERR_01
Inefficient code at the lowest level: needless complexity, nested loops, self-triggering watchEffects.
- ERR_02
TanStack Query used as a global event bus — stores coupled through API calls they shouldn't know about.
- ERR_03
Reactive queries inside watchEffects causing request waterfalls: one call triggered the next, and the next.
- ERR_04
Pull requests without consistent formatting — reviews drowned in noise instead of logic.
What I did
- 01
Introduced hard rules with Biome (lint + format) and git hooks — consistency became automatic.
- 02
Split responsibilities between modules and views, removing cross-store coupling.
- 03
Centralised every API client, query, mutation and query key in one typed layer.
- 04
Built an invalidation engine: specific SignalR messages invalidate exactly the queries they affect.
- 05
Eliminated chained calls driven by reactive queries — plus dozens of smaller fixes.
Outcome
0
request waterfalls left
1
typed source of truth for all queries
RT
targeted real-time invalidation
100%
PRs formatted by machines, reviewed by humans
The result: the application runs as fast as it possibly can — and stays that way, because the rules now enforce themselves.
Got a slow app?
I've seen worse. Let's talk.