5 Build performance into your architecture
This chapter argues that performance is largely an architectural outcome, not something that code tweaks can fix after the fact. It begins by separating speed, scalability, and resilience so teams can diagnose the real problem instead of applying the wrong solution. Speed is about how quickly one user completes one task, scalability is about how performance changes under load, and resilience is about how gracefully the system behaves when parts fail.
The main theme is to design rendering, initialization, and backend systems so users wait as little as possible on the critical path. For the web, that means choosing between all-at-once and progressive approaches such as server-side rendering, streaming, and selective hydration, based on the need for immediate content, interactivity, SEO, and device conditions. The same logic applies to mobile and desktop: initialize only what must run at startup, move everything else off the main thread or behind lazy loading, and choose between native, cross-platform, or hybrid architectures based on the app’s performance sensitivity, resource constraints, and team capabilities.
The chapter then extends the idea of performance-aware architecture to backends and data layers. It explains when monoliths outperform microservices, when edge computing or CDNs reduce latency, how API choices like REST, GraphQL, and gRPC shape round trips and payload cost, and why queues help by pushing non-critical work off the user’s critical path. It also covers database choices such as relational systems, NoSQL, replicas, connection pooling, and indexing, then closes with practical guidance for improving inherited systems through caching, facades, BFFs, async boundaries, and strangler-style migrations rather than risky rewrites unless the architecture is truly blocking progress.
```Server-Side Rendering (SSR)
Client-Side Rendering (CSR)
Streaming SSR
Islands Architecture
The web rendering timeline
Monolith vs microservices latency
CDN latency advantage
Architectural improvement decision tree. If you can improve one piece without touching others, prefer incremental changes like caching or query optimization, which are lower risk and deliver quick wins. If every change forces coordinated modifications across the system, larger architectural changes become necessary despite longer timelines and coexistence costs.
Summary
- Architecture determines the performance ceiling for everything that follows. The goal is not the theoretically fastest system but one where achieving acceptable performance is straightforward and does not require heroic effort.
- Different platforms have different optimal patterns. Web applications choose between server, client, or hybrid rendering. Mobile apps optimize for battery and startup time. Desktop applications must remain responsive during extended sessions. Backend services balance monolith simplicity against microservice flexibility.
- API design affects every request. REST offers simplicity and natural HTTP caching, GraphQL provides client flexibility at the cost of server complexity, and gRPC delivers maximum efficiency for internal services. Backend for Frontend patterns let you tailor responses to specific clients without building one API that tries to serve all platforms.
- Edge computing and CDN strategies move logic and content closer to users. Operations needing only request data or cached content can run at the edge, while database operations require the origin.
- Database architecture shapes query performance. Read replicas scale reads, connection pooling eliminates per-request overhead, proper indexing prevents table scans, and data fetching patterns like parallel requests and prefetching reduce critical path latency.
- Message queues decouple critical path work from background processing, letting users see fast responses while workers handle emails, analytics, and downstream synchronization asynchronously.
Fast by Default ebook for free