Volume 2

Q138: performance.mark, measure and User Timing API

Difficulty: SeniorFrequency: MediumAnswer time: 8-12 minutes

What Interviewers Want To Evaluate

This question checks whether you can instrument frontend performance beyond guessing. Interviewers want performance.mark, performance.measure, PerformanceObserver, user timing entries, custom milestones, cleanup, and how custom timings complement Core Web Vitals.

Senior answers should connect measurements to product workflows.

Short Interview Answer

The User Timing API lets JavaScript record custom performance marks and measurements. performance.mark records a named timestamp, and performance.measure calculates duration between marks. These custom timings help measure product-specific milestones like search results rendered, editor ready, checkout submitted, or dashboard hydrated. They complement browser metrics like LCP and INP by explaining app-specific work.

Detailed Interview Answer

Browser metrics tell part of the story. Product workflows often need custom milestones.

Examples:

search started to results rendered
editor route loaded to interactive
dashboard filters changed to table updated
checkout submit to confirmation visible
import started to validation complete

The User Timing API measures these flows.

performance.mark

performance.mark records a named timestamp.

performance.mark("search:start");

You can place marks at important moments in the workflow.

performance.measure

performance.measure creates a duration entry.

performance.mark("search:start");

await runSearch();

performance.mark("search:results-rendered");
performance.measure(
  "search:time-to-results",
  "search:start",
  "search:results-rendered",
);

This measures elapsed time between two marks.

Reading Measures

const entries = performance.getEntriesByName("search:time-to-results");

Each entry includes timing information such as duration.

PerformanceObserver

PerformanceObserver can observe performance entries.

const observer = new PerformanceObserver((list) => {
  for (const entry of list.getEntries()) {
    console.log(entry.name, entry.duration);
  }
});

observer.observe({ entryTypes: ["measure"] });

This is useful for collecting custom timings centrally.

Custom Metrics vs Core Web Vitals

Core Web Vitals measure user experience signals like loading, responsiveness, and visual stability.

Custom timing answers product-specific questions.

Web Vital: Was the page responsive?
Custom timing: How long until invoice export was ready?

Both matter.

Naming Strategy

Use consistent names.

feature:phase
search:start
search:results-rendered
checkout:confirmation-visible
editor:ready

Clear names make dashboards easier to read.

Cleanup

Marks and measures can accumulate.

performance.clearMarks("search:start");
performance.clearMeasures("search:time-to-results");

For long-running single-page apps, cleanup prevents noisy or excessive entries.

Measuring Render Completion

Be careful about what "done" means.

An async function finishing does not always mean the UI has painted.

Sometimes the milestone should be after state update and next paint.

requestAnimationFrame(() => {
  performance.mark("search:painted");
});

Define milestones from the user's perspective.

Common Mistakes

A common mistake is measuring only API time and calling it UI time.

Another mistake is creating marks but never collecting them.

Another mistake is comparing custom metrics across releases without stable definitions.

Senior Trade-Offs

Instrumentation should be low overhead, consistent, privacy-safe, and actionable.

Do not measure everything. Measure workflows that affect user experience or business outcomes.

Code or Design Example

async function measureWorkflow(name, task) {
  const start = `${name}:start`;
  const end = `${name}:end`;
  const measure = `${name}:duration`;

  performance.mark(start);

  try {
    return await task();
  } finally {
    performance.mark(end);
    performance.measure(measure, start, end);
    performance.clearMarks(start);
    performance.clearMarks(end);
  }
}

This wrapper measures async workflow duration consistently.

Debugging Workflow

When custom performance is unclear:

define user-visible milestone
mark start and finish
observe measure entries
compare API, render, and paint phases
segment by route and device
watch for outliers
validate with performance trace
remove or clean up noisy marks

Interview Framing

Explain mark and measure, then give a product workflow example. Mention PerformanceObserver, cleanup, and user-visible milestone definition.

Revision Notes

User Timing measures app-specific workflows. It complements browser metrics rather than replacing them.

Key Takeaways

Good performance work starts with the right measurement. Custom timings turn vague complaints into observable workflows.

Follow-Up Questions

  1. What does performance.mark do?
  2. What does performance.measure do?
  3. What is PerformanceObserver?
  4. Why create custom timings?
  5. How do custom timings differ from Core Web Vitals?
  6. Why does milestone definition matter?
  7. When should marks be cleared?
  8. How do you measure UI paint?
  9. What makes instrumentation actionable?
  10. What workflows would you measure?

How I Would Answer This In A Real Interview

I would say marks create timestamps and measures calculate durations between them. Then I would describe measuring a real workflow like search time-to-results, collecting entries with PerformanceObserver, and keeping milestone definitions stable.