Measuring & Monitoring
📊 Measuring & Monitoring
Lab Data: Deterministic, Not Representative
Lighthouse runs under fixed, simulated conditions — a specific network throttle profile, a specific CPU multiplier, a specific device emulation. This determinism is exactly its strength: it's the right tool for "did this specific change actually help, holding everything else constant?" It's also exactly its weakness — real users' actual conditions vary enormously and rarely match the simulated profile.
🌍 Field Data: Noisy, But Real
Real User Monitoring (RUM) collects actual measurements from real visitors' real browsers, devices, networks, and locations — inherently noisier than a controlled lab run, but it represents ground truth for what's actually being experienced.
CrUX (Chrome User Experience Report)
Google's public, aggregated field dataset from opted-in real Chrome users — available for free via PageSpeed Insights or the CrUX API, no instrumentation needed. Limited to sites with enough Chrome traffic, Chrome-only, and aggregated over a rolling 28-day window.
The web-vitals Library
Google's own small library for capturing Core Web Vitals directly in the browser, from your own actual visitors — real-time, not Chrome-only, not delayed by a rolling window, and specific to your real traffic mix rather than an aggregate.
Capturing Field Data Directly
Why You Need Both
Lab data lets you iterate quickly with reproducible conditions — real field data can't tell you within seconds whether a specific tweak helped. Field data tells you what's actually happening to real visitors, and confirms a lab-driven fix genuinely helped in the real world. Neither alone tells the full story — echoing exactly Chapter 1's original point.
Lab Alone vs Lab + Field
Lab Data Alone
Scores perfectly in Lighthouse — no visibility into what real 3G users or low-end devices actually experience.
Lab + Field
Fast iteration in the lab, confirmed by real measurements that the fix genuinely helped everyone, not just the simulated profile.
💰 Performance Budgets
Concrete numeric limits — "LCP must stay under 2.5s," "total JS under 300KB," "no single image over 200KB" — checked automatically, often in CI. Performance is a moving target, not a one-time fix: one new dependency here, one new tracking script there, and a fast page slowly becomes slow again without something acting as a guardrail.
💻 Coding Challenges
Challenge 1: Wire Up the web-vitals Library
Write code using the web-vitals library that captures all three Core Web Vitals and logs each metric's name and value to the console instead of sending it anywhere.
Goal: Practice the basic setup for first-party field data collection.
Challenge 2: Diagnose Why Lab and Field Disagree
A page scores "Good" LCP in Lighthouse but CrUX field data shows "Needs Improvement" for real users. Using this chapter's material, explain one plausible cause and which data source you'd trust more for deciding whether the page is actually fast enough.
Goal: Practice applying the lab-vs-field distinction to a real disagreement, not just reciting the definitions.
Challenge 3: Design a Performance Budget
Propose three concrete performance budget rules for a content-heavy blog site (not an app), covering at least one Core Web Vital and at least one byte-weight limit, and briefly justify each threshold.
Goal: Practice setting concrete, enforceable numeric limits rather than vague goals.
Setting a budget once and only reporting or logging violations, rather than actually failing a CI build when a limit is exceeded, means the budget will be silently ignored the first time a deadline pressures a team to ship "just this once" over budget. Every "just this once" compounds — the exact cumulative-regression problem the budget exists to prevent creeps back in through the same door, one small exception at a time. A budget only works as a guardrail if crossing it actually blocks the build; a budget that's merely advisory eventually gets treated as optional.
🎯 What's Next
Every technique from this course comes together in the final chapter: Capstone: Auditing and Fixing a Slow Page — walking a deliberately slow example page through LCP, CLS, and INP fixes, one issue at a time.