Q217: Typed Web Vitals, Analytics and Observability Events
What Interviewers Want To Evaluate
Interviewers want to know whether you can design performance instrumentation that is consistent, typed, and useful.
They check Core Web Vitals event shape, analytics contracts, route metadata, release context, privacy, sampling, dashboards, and how typed events prevent observability drift.
Short Interview Answer
I would define typed event contracts for Web Vitals and product analytics so route, metric, value, rating, release, device, and context fields stay consistent. TypeScript helps prevent inconsistent event names and payloads, but measurement still needs runtime collection, privacy review, sampling, and dashboards. The goal is to connect performance metrics to real user journeys without leaking sensitive data.
Detailed Interview Answer
Performance work depends on reliable telemetry.
If every page logs different fields, dashboards become noisy.
Typed event contracts help standardize:
event names
metric names
route identifiers
release versions
device classes
user journey steps
sampling fields
debug context
privacy boundaries
Web Vitals Event Type
Start with known metric names.
type WebVitalName = "LCP" | "INP" | "CLS" | "FCP" | "TTFB";
type WebVitalRating = "good" | "needs-improvement" | "poor";
Then define the payload.
type WebVitalEvent = {
event: "web_vital";
metric: WebVitalName;
value: number;
rating: WebVitalRating;
route: string;
navigationType: "navigate" | "reload" | "back-forward" | "prerender";
release: string;
};
Now every metric event has the same shape.
Product Journey Events
Performance metrics are more useful with journey context.
type LearningEventPayloads = {
question_opened: { questionId: string; route: string };
question_completed: { questionId: string; secondsSpent: number };
batch_opened: { batchSlug: string };
practice_run: { language: "js" | "ts"; success: boolean };
};
Create a typed tracker.
function trackEvent<TEvent extends keyof LearningEventPayloads>(
event: TEvent,
payload: LearningEventPayloads[TEvent],
) {
console.log(event, payload);
}
Callers cannot send the wrong payload for the event.
Shared Context
Most events need shared fields.
type EventContext = {
release: string;
route: string;
viewport: "mobile" | "tablet" | "desktop";
connection?: "slow" | "average" | "fast";
};
type ObservabilityEvent<TName extends string, TPayload> = {
name: TName;
payload: TPayload;
context: EventContext;
timestamp: string;
};
This keeps dashboards filterable.
Privacy Boundary
Typed events should exclude sensitive fields by design.
Avoid:
email
full name
raw query text
access token
full URL with secrets
private document content
Prefer:
stable anonymous id
route pattern
question id
batch slug
coarse device class
release id
metric value
Privacy is part of telemetry architecture.
Rating And Thresholds
Ratings should be derived consistently.
function rateLcp(value: number): WebVitalRating {
if (value <= 2500) return "good";
if (value <= 4000) return "needs-improvement";
return "poor";
}
Keep threshold logic centralized.
Otherwise different dashboards disagree.
Sampling
High-volume telemetry may need sampling.
type SampledEvent<T> = T & {
sampleRate: number;
};
Sampling should be explicit.
If only 10 percent of events are sent, dashboards need to know that.
Error And Performance Correlation
Typed events can share context with errors.
type RuntimeErrorEvent = {
event: "runtime_error";
message: string;
route: string;
release: string;
component?: string;
};
If Web Vitals and errors share release and route fields, investigations become faster.
Dashboard Value
Good event contracts allow questions like:
Did Q215 route LCP regress after this release?
Do TypeScript practice users see worse INP on mobile?
Which batch pages have the highest abandonment?
Did a third-party script increase long tasks?
Are errors and poor INP correlated on one browser?
Telemetry should answer product and engineering questions.
Common Mistakes
Common mistakes include:
using free-form event names
logging raw sensitive data
missing release or route context
mixing metric units
changing payload shape without versioning
tracking too much without dashboard purpose
assuming TypeScript replaces runtime privacy checks
The worst telemetry is expensive but not actionable.
Senior Trade-Offs
Typed observability is worth it when events are shared across teams or dashboards.
For tiny experiments, lightweight tracking may be enough.
For Core Web Vitals and learning progress, I would standardize event contracts early because historical consistency matters.
Interview Framing
In an interview, say:
I type analytics and Web Vitals events so the data model stays consistent. Then I add privacy rules, sampling, route/release context, and dashboards that answer specific performance questions.
Revision Notes
- Web Vitals events need consistent metric, value, rating, route, and release fields.
- Typed event maps connect names to payloads.
- Shared context makes dashboards filterable.
- Privacy rules should be designed into event contracts.
- Sampling and units must be explicit.
- Telemetry should answer real investigation questions.
Follow-Up Questions
- How would you type Web Vitals events?
- Why should analytics event names be typed?
- What should not be logged?
- How do release and route fields help debugging?
- When would you sample performance events?
How I Would Answer This In A Real Interview
I would say that performance data is only useful if it is consistent. I would define typed Web Vitals and analytics contracts, include route and release context, avoid sensitive data, and centralize rating thresholds. TypeScript keeps event payloads consistent, while runtime collection, sampling, and dashboards make the data operationally useful.