Skip to main content
Card class: Non-HeroCategory: Website Performance

At a glance

First Contentful Paint at the 75th percentile. The time at which the first piece of content (text, image, or non-blank canvas) appears on screen, measured from navigationStart. The earliest “the page is loading” signal users perceive, earlier than LCP. FCP is no longer a Core Web Vital (replaced by LCP for ranking purposes) but remains a useful precursor metric: a slow FCP guarantees a slow LCP since LCP can’t render before the page paints anything at all. Healthy FCP is under 1.8 seconds at p75; over 3 seconds is “poor”.
What it countsThe 75th-percentile of first_contentful_paint measurements across all real-user page-loads in the 28-day CrUX window. The metric measures from navigation start to the moment any content (DOM text, images, non-blank canvas, SVGs) renders.
Sample typeField data sourced from CrUX. Lab equivalent doesn’t have a direct named card but appears in Lighthouse audits as the “First Contentful Paint” sub-metric of the Performance Score (10 percent weight).
Google thresholdsGood: ≤ 1,800ms. Needs improvement: 1,800-3,000ms. Poor: > 3,000ms. FCP is no longer a CWV signal but the thresholds are still part of Lighthouse’s Performance Score calculation.
What drives slow FCP(1) Slow TTFB: FCP cannot fire before the HTML response arrives. A 1,200ms TTFB sets a 1,200ms floor on FCP. (2) Render-blocking resources: synchronous CSS or JS in <head> delays the first paint. (3) Slow CSS-Object-Model construction: very large stylesheets take time to parse. (4) Slow DOM construction: very large HTML (10,000+ DOM nodes) takes time to parse before render can begin.
FCP vs LCPFCP fires when any content paints; LCP fires when the largest content paints. For most ecommerce pages, FCP arrives 200-1,000ms before LCP. The gap matters: if FCP and LCP fire close together (small gap), the LCP element rendered with the first paint, suggesting render-blocking is the dominant issue. If the gap is large (over 2 seconds), the LCP element is loading separately, suggesting image-optimisation or preload work is needed.
Why FCP is no longer a CWVGoogle replaced FCP with LCP in March 2020. Reason: FCP can fire when any tiny element renders (a logo, a single character, a navigation pixel), it doesn’t reflect the user’s perception of “the page is ready”. LCP focuses on the largest element which more closely matches user perception of meaningful content. FCP remains useful as a precursor metric because it’s a leading indicator: improving FCP usually improves LCP too.
Sample size thresholdCrUX p75 calculation requires sufficient real-user volume (~1,000+ page-loads per 28-day window per device).
Currencyn/a, this is a duration in milliseconds.
Time window28D (CrUX-fixed).
Alert trigger> 1,800ms (Google’s good threshold). Sub-thresholds: amber 1,800-3,000ms, red > 3,000ms.
Sentiment keypsi_fcp
Rolesowner, marketing, operations

Calculation

Calculated automatically from your Website Performance (PageSpeed + CrUX) data. See the At a glance summary above for what the metric tracks and the worked example below for a typical reading.

Worked example

A UK-based BigCommerce fashion store, mobile field-data measurement Wednesday 15 May 26.
Page templateMobile FCP p75Mobile LCP p75LCP-FCP gapDiagnosis
Homepage2,640ms4,820ms2,180msWide gap: hero image loads separately
Product detail page2,180ms3,640ms1,460msModerate gap: product hero image
Collection page2,820ms4,210ms1,390msModerate gap: 12-image grid first image
Cart1,680ms2,180ms500msTight gap: page light, no media drag
Checkout1,320ms1,940ms620msTight gap: lightest pages
Origin p752,540ms4,820ms2,280msFCP needs improvement; LCP poor
What the per-template view is telling us:
  1. Origin FCP at 2,540ms is in the “needs improvement” band. Real users see the first painted content roughly 2.5 seconds after navigation, with 25 percent of users experiencing 3+ seconds. Improving FCP also improves LCP because LCP can’t fire before FCP, but they’re not 1:1.
  2. The TTFB-FCP relationship: with TTFB at ~1,180ms (per psi_server_response), FCP fires roughly 1,360ms after the HTML arrives. This 1,360ms is “render preparation time”, CSS download + parse + layout + first paint. Render-blocking CSS is the likely culprit for the FCP-after-TTFB gap; reducing render-blocking resources should drop FCP toward 1,500ms.
  3. The LCP-FCP gap of 2,280ms on the homepage is wide, telling us the LCP element loads separately from the initial paint. The hero image arrives 2.2 seconds after the page first paints. Two-stage fix: (a) fix FCP via render-blocking CSS reduction; (b) preload the LCP element so it arrives near FCP rather than 2 seconds later. Combined, expect the homepage’s mobile p75 LCP to drop from 4,820ms to roughly 2,400ms.
  4. PDP and collection pages have moderate gaps (1,400ms range). Same fix-pattern: address render-blocking + preload the largest above-the-fold image.
  5. Cart and checkout have tight gaps and healthy absolute values. No optimisation needed; they’re already fast. The gap is small because these pages have no large above-the-fold media.
  6. The optimisation sequencing: address FCP first because it’s upstream of LCP. Fix render-blocking CSS (covered in psi_render_blocking) → FCP drops 200-500ms → LCP drops by similar amount as a side effect. Then address LCP-specific issues (image preload, format conversion) for the remaining gap.
  7. Implications for engineering: don’t optimise LCP before FCP. The two-stage fix sequence is more efficient than parallel work because FCP improvements automatically lift LCP, and FCP work (render-blocking) is mostly different from LCP work (image preload + format).
The diagnostic flow when this card flags amber/red:
  1. Cross-reference with crux_ttfb_p75. Slow TTFB sets the FCP floor; fix TTFB first if it’s amber/red.
  2. Check render-blocking resources. psi_render_blocking surfaces CSS/JS in <head> blocking first paint.
  3. Compare to LCP. Wide LCP-FCP gap = LCP-element loading issue. Tight gap = render-blocking is the dominant issue.
  4. For low-traffic sites with null FCP, fall back to lab measurements via psi_perf_score_summary.
Rapid-response playbook:
Time horizonAction
First 1 hourCross-reference TTFB and render-blocking diagnostics.
First 24 hoursApply render-blocking fix (defer non-critical CSS/JS).
First 7 daysField FCP partial movement.
Day 28Field FCP fully reflects fix. Re-evaluate LCP.

Sibling cards merchants should reference together

CardWhy merchants reach for it
crux_lcp_p75LCP cannot fire before FCP; FCP improvement lifts LCP.
crux_ttfb_p75TTFB is upstream of FCP; slow TTFB sets the FCP floor.
crux_fcp_trendFCP over time; drift detection.
psi_render_blockingRender-blocking resources delay FCP directly.
psi_speed_indexSpeed Index integrates the visual completeness curve including FCP.
psi_perf_score_summaryComposite score; FCP is 10 percent of weight.
crux_cls_p75Sister CWV.
crux_inp_p75Sister CWV.
psi_cwv_pass_rateAll-three CWV gate (excludes FCP since FCP is no longer a CWV).

Reconciling against the vendor’s own dashboard

Where to look: Why the Vortex IQ FCP may differ from PSI:
ReasonDirectionWhat to do
Window timing. Vortex IQ refreshes daily; CrUX has 1-2 day lag.Vortex IQ lagsWait for next refresh.
Origin vs URL. Different aggregation.Different scopeUse per-URL view for direct comparison.
Form factor. Mobile vs desktop.n/a if both mobileConfirm form factor.
Cross-connector reconciliation: primarily internal (with crux_lcp_p75, crux_ttfb_p75). Quick rule for support tickets: if a merchant says “my FCP improved but my LCP didn’t”, the LCP element is loading separately from the initial paint. Investigate image preload, format optimisation, or render-blocking on the LCP element specifically.

Known limitations / merchant FAQs

Why was FCP replaced by LCP as a CWV? FCP fires too easily, a logo, a single character, or a navigation pixel can trigger it without reflecting “the page is ready”. LCP focuses on the largest content element which more closely matches user perception of meaningful content. Google made this change in March 2020 to better align CWV with perceived performance. Should I still optimise FCP? Yes, indirectly. FCP improvements automatically lift LCP because LCP can’t fire before FCP. Optimise FCP first (render-blocking resources, TTFB) and LCP improves as a side effect. Then tackle LCP-specific issues (image preload, format conversion) for the remaining gap. My FCP is healthy but LCP is poor. What’s going on? The LCP element is loading separately from the initial paint. Common cause: large hero image that arrives 1-3 seconds after the page paints text + small images. The fix: preload the LCP image so it downloads in parallel with the critical render path; convert format for smaller bytes; serve responsive variants for mobile. Why is my FCP slow if my TTFB is fast? Render-blocking resources. The HTML arrived quickly (fast TTFB) but external CSS or synchronous JS in <head> is blocking the first paint. The browser has to download + parse those resources before painting anything. Fix render-blocking (psi_render_blocking) to drop FCP toward TTFB + 200-400ms. Can I make FCP under 1 second? Possible but rarely needed. Sub-1s FCP requires aggressive edge caching (TTFB under 200ms) plus inlined critical CSS plus minimal blocking resources. For typical ecommerce, 1.2-1.6s FCP is excellent; pushing below that has diminishing returns. Why isn’t FCP a Core Web Vital anymore? It’s still a Lighthouse Performance Score component (10 percent weight) but not a ranking signal in Google’s CWV. The transition was March 2020. For ranking, only LCP, INP, CLS matter; FCP is for engineering iteration. Can Vortex IQ improve FCP automatically? Read-only. Vortex IQ identifies the issue; engineering implements.

Tracked live in Vortex IQ Nerve Centre

First Content Visible is one of hundreds of KPI pulses Vortex IQ tracks across Website Performance (PageSpeed + CrUX) and 70+ other ecommerce connectors. Nerve Centre runs the detection layer; Vortex Mind investigates the cause when something moves; Ask Viq lets you interrogate any number in plain English. Start for free or book a demo to see this metric running on your own data.