Skip to content
⚠️ This article was written in 2018. Some content may be outdated.

Frontend Performance Metrics: What Are FCP, TTI, and FID?

I've been doing performance optimization lately and realized that many people (including myself) have a fuzzy understanding of performance metrics. Here's a summary of the key ones.

Core Metrics

FP (First Paint)

The time when the browser first renders any pixel. It might just be a background color — user perception is weak at this point.

FCP (First Contentful Paint)

The time when text, images, SVGs, or non-white canvas are first rendered. The moment the user first sees "content."

Target: < 1.8 seconds (Google standard)

LCP (Largest Contentful Paint)

The time when the largest block of text or image within the viewport completes rendering. Represents when the main content has loaded.

Target: < 2.5 seconds

TTI (Time to Interactive)

The time when the page is fully able to respond to user actions (main thread is idle, event handlers are attached).

Target: < 3.8 seconds

FID (First Input Delay)

The delay between the user's first interaction (click, input) and when the browser actually starts processing it.

Target: < 100ms

CLS (Cumulative Layout Shift)

The total amount of unexpected layout shifts during page load. Images without specified dimensions and dynamically injected content cause high CLS.

Target: < 0.1

How to Measure

Chrome DevTools

Performance panel → Record → Check the Timings section

Lighthouse

bash
npm install -g lighthouse
lighthouse https://example.com --output html --output-path report.html

Performance API (Measure in Code)

javascript
// Listen for FCP
const observer = new PerformanceObserver((list) => {
  for (const entry of list.getEntries()) {
    if (entry.name === "first-contentful-paint") {
      console.log("FCP:", entry.startTime, "ms");
    }
  }
});
observer.observe({ entryTypes: ["paint"] });

// Get navigation timing (TTFB, etc.)
const timing = performance.getEntriesByType("navigation")[0];
console.log("TTFB:", timing.responseStart - timing.fetchStart);
console.log("DOM Ready:", timing.domContentLoadedEventEnd - timing.fetchStart);
console.log("Page Load:", timing.loadEventEnd - timing.fetchStart);

Common Issues and Optimization Directions

Poor MetricPossible CauseOptimization Direction
Slow FCPJS blocking render, slow font loadingReduce blocking resources, inline critical CSS
Slow LCPLarge images, slow serverImage optimization, CDN, preload critical images
Slow TTIToo much JS, busy main threadCode splitting, reduce JS
High FIDLong tasks blocking main threadBreak up long tasks, defer non-critical JS
High CLSImages without dimensions, ad injectionSpecify width/height for all images/videos

Summary

  • FCP: when the user sees content (< 1.8s)
  • LCP: when the main content finishes loading (< 2.5s)
  • TTI: when the page is truly interactive (< 3.8s)
  • FID: response delay on first click (< 100ms)
  • CLS: layout stability (< 0.1)
  • Run Lighthouse regularly to spot issues

MIT Licensed