0 / 91
Week 13 · Day 88 of 91

Performance and usability pass

Capstone Completion and Professional Handoff

Objective

Measure obvious bottlenecks and remove friction without premature optimization.

The final phase is commissioning and handoff: validate under expected conditions, document limitations, and leave the next engineer a maintainable system.

  • network request count
  • slow query evidence
  • form and navigation usability

Why this matters

Your app works and it recovers from failure. Today you find out whether it is actually pleasant to use — and you find out with numbers, not opinions. By the end of the hour you will have one measured performance improvement with a before and after, and a written list of usability friction found by walking through your own app as a stranger would.

The discipline being taught is small and permanent: measure and identify an actual bottleneck before you optimise anything.

Why measuring comes first

Premature optimisation is changing code to make it faster before you know what is slow. It costs real time, adds complexity, and usually speeds up something nobody was waiting on. Human intuition about performance is unreliable — the slow thing is almost never the clever loop you worried about; it is a missing index or forty round trips.

So the rule is: reproduce it, measure it, name a number, change one thing, measure again. If you cannot state the before and after numbers, you did not optimise — you edited.

Probe before you desolder

When a supply rail sags you do not start replacing capacitors because one looks suspect. You put a scope on the rail, find where the droop appears, and then change the one component in that path. Measuring costs two minutes; guessing costs an afternoon and leaves a board with rework on it. DevTools and EXPLAIN ANALYZE are your probes.

Network request count

Every request from the browser to your server is a separate round trip with its own latency. Ten requests that each take 80 ms cost most of a second even if the server does no real work.

Open DevTools → Network, tick Disable cache, and reload the screen. Read three things off the bottom bar: how many requests, how much was transferred, and how long until the page finished. Then sort by the Time column and look at the top row.

The pattern to hunt for is the N+1 request: one request to fetch a list of twenty records, then twenty more requests, one per row, to fetch each record's details. In the waterfall it is unmistakable — a single bar, then a staircase of near-identical bars. The fix is on the server: return what the screen needs in one response, the way you designed your endpoints in Week 6.

Two minutes, right now

Open your busiest screen with the Network panel recording and cache disabled. Write down the request count and the finish time. That number is your baseline for the rest of today, and you cannot claim an improvement without it.

Throttling makes slow things visible. Use the throttling dropdown in the Network panel (the preset names vary by Chrome version — pick one of the slow mobile profiles) and use your app for a minute. Everything you were tolerating at LAN speed becomes obvious.

Slow query evidence

On the server, the usual culprit is a query reading far more rows than it returns. PostgreSQL will tell you exactly what it did if you ask with EXPLAIN ANALYZE, which runs the query and reports the plan with real timings.

EXPLAIN ANALYZE SELECT * FROM maintenance_records WHERE equipment_id = 3;
Seq Scan on maintenance_records  (cost=0.00..412.00 rows=18 width=64)
                                 (actual time=0.021..3.284 rows=18 loops=1)
  Filter: (equipment_id = 3)
  Rows Removed by Filter: 19982
Planning Time: 0.114 ms
Execution Time: 3.301 ms

Read three lines. Seq Scan means the database walked the whole table. Rows Removed by Filter: 19982 means it examined twenty thousand rows to return eighteen. Execution Time is the number you are trying to move.

That is what an index is for — the ordered lookup structure you met on Day 48:

CREATE INDEX idx_records_equipment_id ON maintenance_records (equipment_id);
EXPLAIN ANALYZE SELECT * FROM maintenance_records WHERE equipment_id = 3;

Now the plan says Index Scan using idx_records_equipment_id and the rows-removed line is gone. Record both execution times; that pair is your evidence.

Indexes are not free and small tables do not need them

Every index must be updated on every insert and update, so indexing every column slows writes for no gain. Also, on a table of 50 rows PostgreSQL may correctly ignore your index — a sequential scan really is faster there. Add an index because a plan showed a problem, not on principle.

The server has its own N+1: a loop that runs one query per item. Your Day 54 request logging shows it as one endpoint whose duration grows with the size of the list. A join, or one query with WHERE id = ANY($1), replaces the loop.

Form and navigation usability

Usability problems are found by doing tasks, not by looking at screens. Pick five real tasks — sign in, create a record, find a specific record, edit it, sign out — and do each one while writing down every moment of hesitation. Hesitation is data.

What to look for specifically:

  • Forms. Is every field labelled, and does clicking the label focus the field (your Day 10 work)? Are errors shown next to the field that is wrong, not only at the top? Is the submit button disabled while the request is in flight, so a double-click cannot create two records? Are required fields marked before submission rather than discovered after?
  • Navigation. Does the browser Back button do the sensible thing from every screen? Can you reach the main task from the home screen in one click? After you save, does the app take you somewhere useful, or leave you on a form you already finished?
  • Feedback. Does anything that takes time say so? Does a successful save confirm visibly?

Then use the app once with the keyboard only: Tab to move, Enter to activate. If you cannot complete a task, or you cannot see which element has focus, that is a real defect — for keyboard users it is a blocker, and it is usually a two-line fix.

Watching someone read your directions

You wrote directions to your house and they are correct. Then you watch someone follow them and see them stop at the roundabout every time, because "second exit" is ambiguous at speed. You did not learn that by re-reading your own note. The five-task walkthrough is watching someone use the directions — and today you play both parts.

Walkthrough

Do one full measure–fix–measure cycle.

  1. Baseline the screen. Network panel, cache disabled, reload. Record request count, transfer size, and finish time.
  2. Find the worst offender. Sort by Time. Note the URL of the slowest request.
  3. Baseline the server side. Run that endpoint's query under EXPLAIN ANALYZE in psql and record the execution time and whether it says Seq Scan.
  4. Change exactly one thing. Add the index the plan justifies, or collapse an N+1 into a single request. One change, so the measurement means something.
  5. Re-measure both. Same conditions — cache still disabled, same throttling setting.
  6. Write it down in docs/performance.md: what was slow, the evidence, the change, the before and after numbers.

Checkpoint

You can say a sentence of this form out loud: "The records list took 1.9 s and 22 requests; EXPLAIN ANALYZE showed a sequential scan removing 19982 rows; I added an index on equipment_id; it now takes 0.6 s and 3 requests."

Your turn

  1. Baseline your three main screens: request count, transferred bytes, finish time. Table them in docs/performance.md.
  2. Identify one N+1 pattern, in the browser or the server. If there genuinely is none, take the slowest endpoint instead.
  3. Run EXPLAIN ANALYZE on the query behind your slowest endpoint. Save the plan output.
  4. Make one evidence-based improvement and re-measure under identical conditions.
  5. Run the five-task usability walkthrough and write every hesitation in docs/usability.md.
  6. Repeat the five tasks keyboard-only and add what breaks.
  7. Fix the cheapest two usability items today; leave the rest as a prioritised list.

Reviewer mode — with your measurements in hand

Today's mode is reviewer. A useful review produces specific, actionable findings backed by evidence, not general praise and not a wholesale rewrite.

"Require evidence before suggesting optimization. Separate measured bottlenecks from stylistic preferences."

Paste your plan output and your timings. Reject any suggestion that cannot point at one of them.

Common pitfalls

  • Optimising without a baseline. With no before number, "it feels faster" is all you have, and it is usually wrong.
  • Measuring with the cache on. Your second load is fast for reasons your users will not get. Tick Disable cache.
  • Changing several things at once. Two changes and one measurement tells you nothing about either.
  • Treating usability notes as opinions. "I paused for four seconds looking for the save button" is an observation about a real person. Write it down and rank it.

Verify it yourself

Open today's reference, MDN's How the web works, and find where it describes the request and response cycle between browser and server.

  1. This lesson claimed each request is a separate round trip with its own latency cost. Find the part of the page that supports or complicates that claim.
  2. MDN describes components of the journey this lesson skipped — DNS, TCP, and the server's own processing. Which of them would your index change actually affect? Write one sentence explaining why the others were untouched.

Add both answers to docs/performance.md. Knowing which layer your fix acted on is what stops the next optimisation from being a guess.

The hour

  1. 0–5 min Recall

    Without notes, state yesterday’s main idea and one unresolved question.

  2. 5–20 min Learn

    Read only the listed concept notes and official reference sections needed today.

  3. 20–48 min Build

    Use DevTools and logs to identify one measured performance issue and conduct a five-task usability walkthrough.

  4. 48–55 min Explain and verify

    Run the result, inspect evidence, and explain the data/control flow in your own words.

  5. 55–60 min Quiz and commit

    Complete the quiz, record one lesson, and commit the verified change when applicable.

What to hand in

Deliverable

One evidence-based performance improvement and a usability fix list.

Working with AI today

AI as skeptical reviewer

Provide existing work and ask for concrete defects, risks, missing tests, and unsupported assumptions—not praise.

Require evidence before suggesting optimization. Separate measured bottlenecks from stylistic preferences.

References

End-of-day quiz

Q1 What should happen before optimization?
Q2 Which result best proves today’s work is complete?
Q3 What should an AI code review primarily produce?

Explain-back gate

Pass the quiz above to unlock completion.

Quiz + explain-back checks required.