Problem Statement and Applicable Context
An ecommerce product page has 28-day mobile field data with p75 LCP of 4.1 seconds, INP of 320 milliseconds, and CLS of 0.06. Desktop passes all three metrics. A developer's local Lighthouse run reports LCP of 1.8 seconds, TBT of 80 milliseconds, and CLS of 0.01. Explain how you would reconcile the discrepancy, locate the LCP and INP root causes, order the fixes, and prove that the deployed changes improved real user experience.
Use the current “good” Core Web Vitals thresholds: calculate the 75th percentile separately for mobile and desktop, with LCP at or below 2.5 seconds, INP at or below 200 milliseconds, and CLS at or below 0.1. The numbers are interview assumptions, not measurements from any real company. The goal is not to recite an optimization checklist. It is to connect user distributions, metric components, browser work, and validation into a falsifiable diagnostic chain.
This question fits senior frontend, web performance, and full-stack interviews. A candidate needs to understand network waterfalls, the main thread, and layout, while also recognizing that one Lighthouse run cannot overrule real-user data and that TBT is not INP.
What the Interviewer Is Evaluating
First, can the candidate normalize the evidence before acting? A strong answer establishes whether the field data represents one URL, a URL group, or the whole origin, then segments by mobile versus desktop, route template, device tier, network, geography, and release. A weak answer declares the problem nonexistent because a local Lighthouse score is green.
Second, can the candidate map each metric to a distinct bottleneck? LCP concerns when the main content appears. INP covers the full delay from an interaction to the next rendered frame. CLS covers unexpected visual movement. They share some main-thread and rendering costs, but “reduce the bundle” cannot explain every failure.
Third, can the candidate attribute the latency? LCP can be decomposed into TTFB, resource load delay, resource load duration, and element render delay. One interaction's latency can be decomposed into input delay, processing duration, and presentation delay. A fix should target an abnormal component rather than a random item from a performance checklist.
Fourth, can the candidate use field and lab tools correctly? RUM and CrUX identify what real users experience. DevTools, Lighthouse, and a reproducible constrained-device scenario help explain why. Without actual user input, Lighthouse cannot measure INP; laboratory signals such as TBT are diagnostic aids.
Fifth, can the candidate prove improvement rather than merely show a deployment? After release, compare like-for-like RUM distributions by version or rollout cohort, check error and business guardrails, and then let the rolling 28-day field data confirm the change. One snapshot, a lower mean, or one faster phone does not prove that p75 passes.
Questions to Clarify Before Answering
- What is the field-data scope? URL, URL-group, and origin results can differ. If 4.1 seconds belongs to the origin, the product page is not yet the proven cause. If it belongs to the product template, segment that template's traffic further.
- Which devices, networks, and regions contribute the mobile samples? A failure confined to lower-end devices or one region requires a different reproduction and priority. Combining mobile and desktop hides the problem.
- When did the metrics regress? Alignment with a release, third-party script, image pipeline, or traffic-mix change narrows the hypotheses. A rolling 28-day value does not expose one release's immediate effect precisely.
- What are the actual LCP element and slow INP interaction? A hero image, heading text, and client-rendered container need different fixes. Add-to-cart, variant selection, and search input also exercise different main-thread paths.
- How was Lighthouse run? Device and network throttling, cache, authentication, page data, and the tested journey should resemble the slow population. One cold load on a fast laptop does not represent the mobile distribution.
- Which layers may the team change? A frontend-only team should still quantify TTFB but cannot pretend it can directly fix the origin. If CDN, server rendering, and image services are in scope, the plan can cover the full critical path.
- What defines a successful release? Here, all three mobile p75 metrics must be good while error rate, conversion, and accessibility remain safe. Painting the wrong hero image earlier or blocking a critical interaction is not success.
The 30-Second Answer
“I would first verify whether 4.1 seconds and 320 milliseconds are mobile URL-level or origin-level field data, then segment by route template, device, network, and release. Lighthouse TBT is not INP, so the local result cannot dismiss a real-user problem. I would use RUM to identify the actual LCP element and slowest interaction, then capture a network and Performance trace on a comparable device. I would break LCP into TTFB, discovery, download, and rendering, and break INP into input, event processing, and next-frame presentation. CLS already passes at 0.06, so it becomes a regression guardrail rather than the first investment. Finally, I would roll out gradually, compare like-for-like RUM p75 and guardrails, and wait for the 28-day CrUX window to confirm.”
Step-by-Step Deep Dive
Step 1: Explain how field and lab results can both be correct
Twenty-eight days of field data combine real users' devices, networks, cache states, page lifecycles, and interactions. A mobile p75 LCP of 4.1 seconds places roughly the slowest quarter of relevant visits at 4.1 seconds or worse. It does not mean that one “typical phone” takes exactly 4.1 seconds. Passing desktop data suggests the failure may concentrate in constrained CPUs, mobile networks, a mobile template, or a mobile user journey.
Local Lighthouse is a controlled experiment. It is repeatable and useful for waterfalls and regression detection, but it represents one device and network configuration. Without user input, Lighthouse cannot directly produce INP. TBT of 80 milliseconds is a lab signal about main-thread blocking. A page may have low startup TBT but run a 300-millisecond task when a user opens the variant picker. The reverse is also possible: high lab TBT may occur at a time when few real users interact.
First confirm in PageSpeed Insights or the data platform whether the result is URL, origin, or URL-group data, and inspect mobile and desktop separately. Then use first-party RUM to segment by page template, device tier, effective connection type, geography, navigation type, and application release. Each dimension needs enough samples and a defensible privacy boundary. Performance diagnosis does not justify collecting complete query strings, typed text, or user identity.
Step 2: Build RUM that attributes problems instead of only reporting scores
A minimal implementation can report all three metrics through web-vitals. The following code is identical in all three language versions:
import { onCLS, onINP, onLCP } from 'web-vitals';
function sendToAnalytics(metric) {
const body = JSON.stringify({
name: metric.name,
value: metric.value,
id: metric.id,
rating: metric.rating,
route: location.pathname,
});
(navigator.sendBeacon && navigator.sendBeacon('/rum', body)) ||
fetch('/rum', { body, method: 'POST', keepalive: true });
}
onCLS(sendToAnalytics);
onINP(sendToAnalytics);
onLCP(sendToAnalytics);The example uses location.pathname for readability. Production code should map it to a low-cardinality route template such as /products/:id and attach a release, device tier, and the necessary attribution fields. Do not transmit query parameters, DOM text, or user-identifying information. metric.id helps distinguish metric events for a page visit, but the receiving service still needs explicit sampling and duplicate-report rules.
Storing only name and value is not enough to fix a regression. LCP needs the element and four timing components. INP needs the interaction target and three timing components. CLS needs the shifted elements and lifecycle phase. Use an attribution build or an existing RUM product to add those fields. At aggregation time, calculate percentiles from each navigation's final metric. Do not calculate p75 for each component independently and add them: those percentile observations can come from different visits.
Step 3: Diagnose LCP with four timing components
One representative slow mobile navigation shows TTFB of 0.6 seconds, resource load delay of 1.5 seconds, resource load duration of 0.9 seconds, and element render delay of 1.3 seconds, for a total LCP of 4.3 seconds. These components belong to the same navigation, so they can be added. They are not four independent p75 values.
The two largest suspicious components are load delay and render delay. Check whether the hero is inserted only after client JavaScript runs or is incorrectly lazy-loaded. For an image, put the <img> and its src or srcset in the initial HTML, supply correct sizes, do not lazy-load the above-the-fold LCP image, and use higher fetchpriority only for a genuinely critical resource. If CSS is the only discovery path, evaluate a precise preload. Preloading every large image makes critical resources compete for bandwidth.
Another 1.3 seconds passes after the resource finishes downloading, so further image compression may merely shift time into render delay. Inspect synchronous JavaScript, client-rendering gates, blocking styles, fonts, and state that hides the hero. Server-rendering visible hero content, reducing critical CSS, and deferring noncritical hydration can help, but a new trace must show that the target component actually fell. TTFB of 0.6 seconds still deserves monitoring. It has lower priority than the measured 1.5- and 1.3-second delays in this sample; it is not permanently exempt from optimization.
Step 4: Diagnose INP with three timing components
One representative slow “select variant” interaction takes 350 milliseconds: 140 milliseconds of input delay, 120 milliseconds of event processing, and 90 milliseconds of presentation delay. The three components come from one interaction, so their sum is meaningful. The field p75 INP of 320 milliseconds is a separate aggregate and cannot be replaced by this trace.
The input delay means other work already occupied the main thread when the user acted. Record a Performance trace starting before the interaction and look for script evaluation, third-party tags, timers, or hydration long tasks. Break interruptible work into smaller tasks, defer noncritical work, and avoid concentrating it during startup. Shortening only the current click handler does not remove the 140 milliseconds spent waiting before that handler starts.
Processing duration belongs to the event callbacks. Put the selected state or loading feedback into the next frame before inventory analysis, recommendation refreshes, or logging; remove duplicate computation and narrow the state update. For presentation delay, inspect large DOM updates, forced synchronous layout, and layout thrashing. Group DOM reads and writes and reduce the region that must be laid out and painted for this interaction. Change one measured bottleneck at a time and repeat the same journey to compare all three components.
Step 5: Turn the already-good CLS into a regression guardrail
CLS of 0.06 is below 0.1, so it should not outrank failing LCP and INP. It still needs protection because earlier hero loading, a replacement image component, or new interaction feedback can introduce layout shifts. Give images and videos width, height, or a stable aspect-ratio; reserve space for ads, recommendations, and asynchronous content; and control size differences between web fonts and fallbacks.
The gap between lab CLS of 0.01 and field CLS of 0.06 is useful evidence. Default Lighthouse runs mainly cover loading, while real users may see post-load shifts while scrolling, opening components, or keeping a long page active. Use RUM attribution and the DevTools Layout Shifts track to reproduce those journeys. Layout shifts inside a cross-origin iframe may appear in CrUX but cannot be fully attributed through the top page's Web APIs, so inspect embedded content when that discrepancy appears.
Step 6: Order changes by evidence and release gradually
Do not create separate “image” and “JavaScript” projects and change everything in parallel. The current traces suggest that delayed client-side discovery of the hero and startup long tasks may raise both LCP load/render delays and INP input delay. A first batch can test one shared hypothesis: make the hero discoverable in the initial HTML and defer JavaScript that the first screen does not need. The change stays small, the causal claim stays testable, and both failing metrics may improve.
Write an expected signal for each change. Hero discoverability should reduce resource load delay. Reducing startup long tasks should lower LCP render delay, INP input delay, and lab TBT. If the corresponding component does not move, do not credit that fix for a coincidental score change. Image quality, error rate, time until the page is usable, conversion, and accessibility are guardrails so a performance number cannot hide product degradation.
Release to a traffic cohort while retaining a comparable old version or concurrent baseline. Compare the same route, mobile population, and release while checking that traffic mix did not shift materially. When a deployment overlaps with a traffic change, a before-and-after timeline shows correlation, not automatic causation.
Step 7: Close the issue with three layers of evidence
The first layer is a pre-merge lab guardrail: fix the constrained mobile profile, cache state, and critical interactions, then record LCP, TBT, CLS, the network waterfall, and Performance traces. This catches obvious regressions but does not replace real INP.
The second layer is post-release RUM. Check sample size, stable sampling, and metric-event deduplication, then compare p75 LCP, INP, and CLS for the mobile product template along with their components and product guardrails. Short-term RUM can reveal direction quickly. If the sample is insufficient, report insufficient confidence rather than claiming that all users pass.
The third layer is the rolling 28-day confirmation in CrUX or Search Console. Old visits leave the window gradually, so the metric does not jump to its new steady state on deployment day. Passing means mobile and desktop separately meet all three p75 targets: LCP ≤ 2.5 seconds, INP ≤ 200 milliseconds, and CLS ≤ 0.1. Fixing LCP must not push CLS from 0.06 across its threshold. Record rollback criteria and any remaining slow segments so an aggregate pass does not hide a lower-end-device problem.
High-Quality Sample Answer
“I would not use a green local Lighthouse result to dismiss mobile field data. First I would determine whether 4.1 seconds belongs to the product-detail URL, a URL group, or the origin, then segment mobile by device, network, region, and release. A 28-day p75 is a distribution, not one device, and Lighthouse TBT is not INP.
I would add RUM attribution to identify the real LCP element and slowest interaction, then capture traces on a comparable device. Suppose one slow navigation has LCP components of 0.6, 1.5, 0.9, and 1.3 seconds. I would attack the 1.5-second discovery delay and 1.3-second render delay first: put the hero image in the initial HTML, remove above-the-fold lazy loading, and reduce client work that blocks its paint. Compressing an image that has already downloaded is not my first move.
For INP, I would split the slow interaction into input delay, processing, and presentation. If those are 140, 120, and 90 milliseconds, I would first find the startup work occupying the main thread before the interaction, then shorten the callback and reduce layout and paint for the update. CLS already passes at 0.06, so image dimensions and asynchronous-content placeholders remain regression guards.
I would release to a small cohort, require every change to move its predicted timing component, and compare versions with like-for-like RUM and product guardrails. Lab performance budgets prevent pre-merge regressions, RUM gives a fast real-user signal, and the 28-day CrUX window provides final confirmation. I close the issue only when mobile p75 LCP, INP, and CLS all reach 2.5 seconds, 200 milliseconds, and 0.1 without degrading error rate, conversion, or accessibility.”
Common Mistakes
- Dismissing field data because local Lighthouse passes → The two datasets cover different users, time windows, and interactions → Normalize URL, device, network, release, and metric scope first.
- Reading TBT of 80 milliseconds as INP of 80 milliseconds → Lighthouse cannot measure INP without real interactions → Use field INP for impact and TBT plus interaction traces for diagnosis.
- Looking only at a site-wide mean → Averages hide the mobile tail and a failing template → Calculate p75 separately for mobile and desktop, then segment groups with sufficient samples.
- Compressing the image as soon as LCP is slow → Discovery or render delay may dominate → Break LCP into four components and change the abnormal one.
- Preloading every above-the-fold resource → Supposedly critical resources compete with each other → Raise priority only for the confirmed LCP resource and recheck the waterfall.
- Optimizing only the click callback → Long tasks before the callback and layout after it still contribute → Inspect input, processing, and presentation separately.
- Prioritizing CLS from 0.06 to 0.02 → Work goes to a passing metric while LCP and INP still fail → Keep a CLS guardrail and prioritize metrics over threshold.
- Adding four component p75 values → Each percentile may come from a different visit → Add components only within one navigation; calculate the final metric percentile at aggregation time.
- Declaring victory when RUM falls on deployment day → Sample size, traffic mix, and the 28-day window are not stable → Compare rollout cohorts, inspect guardrails, and wait for rolling field confirmation.
Follow-Up Questions and Responses
Follow-up 1: Why is field LCP poor when several test phones cannot reproduce it?
Check whether the field value is for the URL or origin, whether the page template is grouped correctly, and which geography, network, navigation type, or release contains the slow samples. If test devices miss the real tail, take low-cardinality environment labels from slow RUM navigations and recreate comparable CPU, network, cache, and authentication state. If it still cannot be reproduced, preserve online attribution evidence. Repeatedly running fast devices cannot test the problem out of existence.
Follow-up 2: Only one lower-end Android segment fails INP, while global p75 passes. Should you fix it?
Verify that segment's traffic, business importance, and sample reliability. A passing global threshold describes the aggregate distribution, not every important cohort. If the device tier contains many paying users or its INP is far above 500 milliseconds, define a segment SLO and address it. If the sample is tiny, improve observability first. Making every small segment a hard release gate would let sampling noise block releases.
Follow-up 3: How does the plan change if the LCP element is heading text using a web font?
Resource discovery shifts from an image to fonts and blocking styles. Check when the font request is discovered, whether it crosses an origin connection, file size, font-display, and fallback-font dimensions, plus whether the heading waits for client rendering. Do not copy the image fetchpriority plan. Preload only font files that the first screen actually uses, and verify that this does not cause duplicate downloads or displace more critical resources.
Follow-up 4: The slow interaction is inside a cross-origin payment iframe. What can the top page do?
INP can reflect user latency from an iframe interaction, but the cross-origin boundary limits top-page attribution. Correlate RUM with embed version and containing page, use performance evidence from the provider or a reproducible test, and work with that provider. The top page can also reduce its own concurrent long tasks. Without the internal call stack, state the evidence boundary: neither blame the provider automatically nor claim that local code has fixed the iframe.
Follow-up 5: The page has too little traffic for URL-level CrUX data. How do you decide whether it passes?
Use first-party RUM to collect per-visit metrics and necessary environment fields, reporting both sample size and time window, while lab critical-journey tests guard against regressions. Template-level aggregation can increase sample size only when page structure and user journeys are comparable. With insufficient data, you may prove that known traces improved, but you cannot claim a URL-level “good” CrUX status.
Follow-up 6: Rendering the hero earlier improves LCP but starts hydration earlier and worsens INP. What now?
That is a real metric trade-off, so keep both results. Check whether earlier rendering truly requires earlier hydration. Often the static visible content can arrive first while interaction code loads on demand. If immediate interaction is a business requirement, set the budget around the critical user action, split main-thread work, and compare LCP, INP, and conversion during rollout. A composite performance score must not hide an INP regression.
Follow-up 7: Privacy policy forbids storing full URLs and DOM targets. Can RUM still diagnose the issue?
Use predefined route templates, component enums, interaction types, release versions, and coarse device tiers. Do not retain product IDs, query parameters, text, or user identifiers. Map the fields on the client before reporting, and reject high-cardinality values on the server. Attribution becomes less precise, so lab reproduction must fill the gap around the enumerated components and journeys. Performance diagnosis is not permission to expand personal-data collection.