Skip to main content

Data Controls and Large UI Surfaces

The two biggest surfaces in the app are gone:

  • The ticket grid is virtual. Tickets/Search 990 ms → 125 ms; the click issues 3 statements instead of 5,001, and the session holds a page of rows instead of the result.
  • The customer tree loads a level at a time. Customers/LoadTree 510 ms → 62 ms (3,201 statements → 3), Customers/ExpandNode 158 ms → 9 ms.

Both are now inside budget. Evidence and the payload discussion: LargeSurfaces.md.

Run it

cd "LearnWisej-Samples/Performance and Profiling Course/Module 5/WisejPerfLab"
dotnet run -c Release -f net10.0 --urls http://localhost:5805

Module 4 on 5804 is the before.

What to click

ActionWhat you should see
Tickets → Search tickets5,000 rows … 125 ms — within the 300 ms budget, and a moment later 1 page(s) held 1 fetch(es) 201 statements as the grid asks for the rows it is showing
scroll the grid to the middleanother fetch, another page — never a query per cell
Tickets → Redrawa repaint: no query, no row objects
Customers → Load the customer tree8 root nodes 3 SQL statements 62 ms — within the 150 ms budget, each branch labelled (20 below)
Customers → Expand the first branch20 children 3 SQL statements 9 ms — and expanding it again costs nothing, the children are already there
Break the database → searchempty grid, banner, failed=DatabaseUnavailableException
Break the database → expand a fresh branchthe node says (children unavailable) and keeps its placeholder
Run the three scenarios ×3all three medians inside budget for the first time in the course

What changed since Module 4

Models/TicketGridRow.cs new — the six displayed columns, formatted; no entity reaches the UI
Models/TicketRow.cs deleted (replaced by TicketGridRow)
Models/TicketDisplayRow.cs deleted — its last caller went with TicketFormatter.FormatRow
Models/CustomerNodeRow.cs + ChildCount, and a label that carries the count placeholder
Services/TicketQueryService.cs new — Count(filter) and GetPage(filter, first, count)
Services/TicketSearchService.cs deleted
Services/TicketPageCache.cs new — the page cache behind CellValueNeeded
Services/CustomerTreeService.cs rewritten — GetRoots() / GetChildren(id), 3 grouped statements a level
Services/TicketFormatter.cs FormatRow deleted; + FormatMoment
Pages/TicketGridPage.cs virtual mode: RowCount from a count query, CellValueNeeded + DataRead
Pages/CustomerTreePage.cs roots only, placeholder children, load on expand
Forms/TicketDetailForm.cs takes a TicketGridRow
Startup.cs registers TicketQueryService

TicketFormatter.FormatRow — the function at the top of the Module 2 hot path, called 50,000 times per refresh — no longer exists. Module 3 took the dashboard off it, Module 5 took the grid off it, and the last caller went with them. That is the normal ending for a hot function: not making it faster, not calling it.

Known simplifications

  • Update byte counts are not in the docs, because every update here travels over the WebSocket and the Performance API does not report its frames. LargeSurfaces.md says how to read them in the browser's Network panel, and what was measured instead.
  • The export still blocks the request thread and still writes the file a line at a time. Module 6.