Roadmap › .NET Full Stack Developer Interview — End to End › Module: Building a Feature Full Stack
Lessons in this course (10)
7. Performance across the stack
Advanced★ Must knowLesson 7 of 10
Find the slow layer first — measure, don't guess (browser Network tab → API timings/Application Insights → SQL execution plan).
| Layer | Common problem | Fix |
|---|---|---|
| UI | Huge bundles, re-rendering lists, many API calls | Lazy-load routes, OnPush/signals (Angular), memo/virtualised lists (React), batch/combine calls |
| Network | Large JSON, no compression | Paging, projection, response compression, HTTP caching (ETag, Cache-Control) |
| API | Blocking calls (.Result), sync I/O, chatty services | Async all the way, IHttpClientFactory, output caching, parallel independent calls with Task.WhenAll |
| Data access | N+1 queries, tracking big read sets, ToList() too early | Include/projection, AsNoTracking, AsSplitQuery for big graphs, compiled queries |
| Database | Missing index, scans, parameter sniffing, blocking | Execution plan, covering index, update statistics, OPTION (RECOMPILE) where justified, RCSI |
| Caching | Same data loaded every request | IMemoryCache / HybridCache (.NET 9+) / Redis with expiry and invalidation |
csharp
// N+1 (one query for orders + one per order for lines) …
foreach (var o in await db.Orders.ToListAsync()) total += o.Lines.Sum(l => l.Qty); // lazy loading → N extra queries
// … fixed: one query, only the numbers needed
var totals = await db.Orders.Select(o => new { o.Id, Qty = o.Lines.Sum(l => l.Qty) }).ToListAsync();Interview tip: Tell a real story: "Search took 6 s; the plan showed a clustered index scan on 4M rows; I added a covering index on (CustomerId, OrderDate) INCLUDE (Status, Total) and server-side paging — 300 ms."