0.2 — The impact/effort matrix¶
Module 0 · Lesson 2 · 🟢 Foundational · ~20 min
What you'll learn¶
- Every optimization in this course, scored by impact, effort, and risk
- How to sequence work so early wins fund later architecture work
- A repeatable scoring method for your own backlog
How to read the scores¶
| Field | Meaning |
|---|---|
| Impact | Expected p75 improvement on the named metric for a typical large commerce site. Ranges are wide on purpose — yours depends on your baseline. |
| Effort | S = < 2 days · M = 1–2 weeks · L = 1–2 months · XL = a quarter+ with cross‑team dependencies |
| Risk | Chance of user‑visible breakage or revenue regression. Drives whether it needs a flag + A/B holdback. |
| Metric | Which vital it primarily moves |
An optimization with big impact and low effort is not automatically first — do the ones with low risk first, because they build the credibility (and the measurement discipline) you need to be allowed to do the architectural ones.
Tier 1 — Do these first (high impact, low effort, low risk)¶
| # | Optimization | Metric | Impact | Effort | Risk | Lesson |
|---|---|---|---|---|---|---|
| 1 | Install field RUM with attribution | all | Enables everything | S | None | 9.1 |
| 2 | Fix LCP image: priority, correct sizes, no lazy above fold |
LCP | −300 to −1,200 ms | S | Low | 2.1 |
| 3 | Serve AVIF/WebP with correct responsive widths | LCP | −200 to −800 ms | S | Low | 2.1 |
| 4 | preconnect to image CDN + critical API origins |
LCP | −100 to −300 ms | S | None | 2.4 |
| 5 | Self‑host fonts via next/font, subset, display: swap |
LCP/CLS | −150 to −500 ms, −0.05 CLS | S | Low | 2.2 |
| 6 | size-adjust fallback font metrics |
CLS | −0.02 to −0.10 | S | Low | 2.2 |
| 7 | Reserve space for banners, ads, badges, promo bars | CLS | −0.05 to −0.20 | S | Low | 6.3 |
| 8 | Facade the chat widget / video embeds | INP/LCP | −200 to −900 ms TBT | S | Low | 2.3 |
| 9 | Remove duplicate/dead third‑party tags | INP | −50 to −400 ms TBT | S | Medium¹ | 2.3 |
| 10 | Brotli/Zstd on all text assets; verify at the edge | LCP/TTFB | −50 to −250 ms | S | None | 2.4 |
| 11 | Cache-Control: immutable on hashed assets |
LCP (repeat) | −200 to −900 ms | S | Low | 2.4 |
| 12 | Fix bfcache blockers (unload, no-store on nav pages) |
Back nav | −1,000 to −2,500 ms | S | Low | 8.3 |
| 13 | Bundle analyzer + a size budget in CI | JS bytes | Prevents regressions | S | None | 9.2 |
¹ Medium risk only because marketing may depend on a tag you think is dead. Always check with the tag owner and use a 2‑week measurement window.
Expected combined result on a neglected site: LCP −25–40%, CLS to near zero, TBT −30–50%. This is roughly 3 engineer‑weeks.
Tier 2 — High leverage, moderate effort¶
| # | Optimization | Metric | Impact | Effort | Risk | Lesson |
|---|---|---|---|---|---|---|
| 14 | Move 'use client' boundaries down the tree |
JS/INP | −100 to −400 KB | M | Medium | 3.2 |
| 15 | Replace heavy deps (moment, lodash, icon barrels) | JS | −80 to −300 KB | M | Low | 4.3 |
| 16 | Kill barrel‑file imports in the design system | JS/build | −50 to −200 KB, faster builds | M | Low | 4.3 |
| 17 | Dynamic‑import below‑fold & interaction‑only components | JS | −60 to −250 KB | M | Low | 4.2 |
| 18 | Suspense streaming for slow sections (reviews, recs) | LCP/TTFB | −300 to −1,500 ms | M | Medium | 3.3 |
| 19 | Parallelize server data fetches; kill request waterfalls | TTFB | −200 to −900 ms | M | Medium | 7.1 |
| 20 | Route‑level revalidate / ISR for PLP & PDP |
TTFB/LCP | −400 to −800 ms | M | Medium | 3.5 |
| 21 | CDN HTML caching with SWR + surrogate keys | TTFB | −300 to −700 ms | M | High² | 7.2 |
| 22 | Virtualize long PLP grids / tables | INP/memory | −100 to −400 ms INP | M | Medium | 5.4 |
| 23 | Split monolithic contexts; move cart to external store | INP | −80 to −350 ms | M | Medium | 5.3 |
| 24 | startTransition on filters, search, tab switches |
INP | −100 to −500 ms | M | Low | 5.5 |
| 25 | Adopt React Compiler (or fix memoization by hand) | INP | −30 to −200 ms | M | Medium | 5.2 |
| 26 | Optimistic add‑to‑cart with Server Actions | Perceived | Feels instant | M | Medium | 5.6 |
| 27 | Server‑side tag management (move tags off the client) | INP | −100 to −600 ms TBT | M | High¹ | 2.3 |
| 28 | Remove runtime CSS‑in‑JS from hot paths | INP/LCP | −40 to −200 ms | M | Medium | 2.5 |
| 29 | Tighten middleware matcher; move logic out of middleware | TTFB | −20 to −150 ms per request | S–M | Medium | 3.7 |
| 30 | Lighthouse CI + synthetic checks on PRs | all | Prevents regressions | M | None | 9.2 |
² High risk because caching HTML that contains personalized fragments leaks data between users. Never ship this without the safeguards in 7.2.
Tier 3 — Architectural (high impact, high effort)¶
| # | Optimization | Metric | Impact | Effort | Risk | Lesson |
|---|---|---|---|---|---|---|
| 31 | Pages Router → App Router / RSC migration | JS/TTFB | −200 to −500 KB, −300 ms TTFB | XL | High | 3.2 |
| 32 | Partial Prerendering: static shell + dynamic holes | LCP/TTFB | −500 to −2,000 ms | L | High | 3.6 |
| 33 | On‑demand ISR + tag invalidation for 2M+ SKUs | TTFB | −400 to −900 ms | L | High | 3.5 |
| 34 | BFF redesign: persisted queries, response shaping | TTFB | −150 to −600 ms | L | Medium | 7.1 |
| 35 | Multi‑region compute + read replicas | TTFB | −100 to −400 ms (far regions) | L | High | 8.6 |
| 36 | Speculation Rules prerendering for the next click | Perceived | Near‑instant nav | M–L | Medium | 8.1 |
| 37 | Offload heavy compute to Web Workers | INP | −100 to −600 ms | L | Medium | 8.2 |
| 38 | Partytown for third‑party scripts | INP | −200 to −800 ms TBT | M–L | High³ | 8.2 |
| 39 | Service worker for shell + asset caching | Repeat visits | −500 to −1,500 ms | L | High | 8.3 |
| 40 | Edge‑rendered personalization layer | LCP/TTFB | −200 to −600 ms | L | High | 3.7 |
| 41 | Image pipeline overhaul (self‑hosted transform + CDN) | LCP/cost | −200 to −700 ms, big $ | L | Medium | 2.1 |
| 42 | Design‑system perf refactor (zero‑runtime CSS, RSC‑safe) | JS/INP | −100 to −300 KB | XL | Medium | 2.5 |
³ Partytown is powerful and genuinely fragile with tags that need synchronous DOM access. Pilot it on one tag, on one page type, behind a flag.
Sequencing: why order matters more than the list¶
Week 1–2 Measurement (1, 13, 30) ← you cannot manage what you can't see
Week 3–4 Tier 1 quick wins (2–12) ← builds credibility + a real delta to show
Week 5–8 Bundle + boundaries (14–17, 28) ← makes every later change cheaper
Week 9–12 Rendering + data (18–21, 19, 29) ← the TTFB/LCP structural win
Quarter 2 Interaction (22–26) ← INP is a longer grind than LCP
Quarter 2+ Tier 3, one at a time, flagged ← never two architectural changes at once
Three sequencing rules that save projects:
- Measurement before optimization, always. Shipping Tier 1 without RUM means you get no credit for the win and no signal when it regresses.
- Bundle hygiene before interaction work. Halving the JS often halves INP for free, and it makes profiling legible. Profiling a 700 KB bundle is archaeology.
- One architectural change at a time, behind a flag, with an A/B holdback. Two at once and you can't attribute the result — and when revenue dips you'll roll back both.
Scoring your own backlog¶
Use this formula rather than arguing about vibes:
| Factor | Scale | How to fill it |
|---|---|---|
| Impact | 1–10 | Expected p75 metric delta, from a prototype or a similar past change |
| Reach | 0–1 | Share of sessions affected (PDP fix = 0.31 at Aurora; checkout fix = 0.05) |
| Confidence | 0.3 / 0.6 / 1.0 | Guess / measured in lab / measured in field or prior A/B |
| Effort | 1–10 | Engineer‑weeks |
| Risk | 1–3 | 1 = cosmetic, 2 = needs a flag, 3 = revenue‑path change |
Worked example — two candidates at Aurora:
| Candidate | Impact | Reach | Conf. | Effort | Risk | Score |
|---|---|---|---|---|---|---|
Fix PDP LCP image sizes (serving 2200px to a 390px viewport) |
8 | 0.31 | 1.0 | 0.5 | 1 | 4.96 |
| Migrate checkout to App Router | 6 | 0.05 | 0.6 | 8 | 3 | 0.0075 |
The first ships this week. The second is real work but it is not a performance project, and pitching it as one will get it rejected.
The
sizesbug is not a strawman. Serving desktop‑width images to phones is the single most common high‑impact bug in commerce codebases, and it's usually one attribute.
Lab 0.2 — Score your top 10¶
- List the 10 optimizations you think you need.
- Score each with the formula above. Be honest about Confidence — most first attempts are 0.3.
- Sort. Note which of your top 3 you'd have picked by intuition, and which you wouldn't.
- For anything at Confidence 0.3, define the cheapest experiment that would raise it to 0.6 (usually: a local prototype measured with a DevTools trace, or a WebPageTest "block this request" run).
Checklist¶
- Backlog scored, not vibes‑ranked
- Measurement items scheduled before optimization items
- Every Tier 3 item has a flag and an A/B plan attached before it starts
- Nobody is doing two architectural changes simultaneously
Next: 1.1 Why performance pays