v145 · Web APIs · Performance Timing

presentationTime and paintTime in performance entries

Chrome 145 exposes paintTime and presentationTime on element timing, LCP, long animation frame, and paint timing entries. These fields tell you exactly when pixels were committed to the screen — going beyond render start time to capture the compositor handoff.

concepts

  1. Paint Timing Demo

    Observe LCP and element timing entries in real time using a PerformanceObserver. Displays startTime, renderTime, paintTime, and presentationTime for each entry so you can see where the new fields appear and how they differ.

  2. Timing Comparison

    Side-by-side breakdown of all the timing fields on a paint entry — what each measures, typical deltas, and which entries carry which fields. Includes a reference table and a live waterfall.

  3. Compositor Latency Inspector

    Force a new LCP candidate, capture the entry, and draw each phase (startTimerenderTimepaintTimepresentationTime) as bars. Surfaces CPU paint window vs. compositor latency so you can see which phase is slow.

  4. Frame Timeline

    Load images to trigger LCP and element-timing entries, then see every paint phase as a stacked waterfall bar. The Chrome 145 paintTime and presentationTime columns reveal the compositor handoff cost that was previously invisible.

  5. LoAF Presentation Inspector

    Long Animation Frame entries also carry presentationTime. Trigger CPU bursts of adjustable length and see each janky frame's full phase breakdown — script, render, paint, compositor — as a proportional bar. Aggregate stats show average compositor lag across all long frames.

  6. RUM Beacon Builder

    Collects every paint, LCP, and element-timing entry on this page, extracts the Chrome 145 paintTime and presentationTime fields, computes the compositor-handoff delta, and assembles a ready-to-copy navigator.sendBeacon() JSON payload — the exact structure a RUM SDK would ship to analytics.

why it shipped

Existing paint timing metrics (renderTime on LCP entries, startTime on paint entries) capture the moment the browser starts rendering. But rendering involves CPU paint work and then a separate compositor step that hands pixels to the GPU and display. paintTime is when the browser's CPU rasterisation is done; presentationTime is when the frame is actually presented on screen. Chrome 145 surfaces both so developers can diagnose whether latency is in layout+paint or in the compositor pipeline.

the API

const observer = new PerformanceObserver(list => {
  for (const entry of list.getEntries()) {
    console.log('type:             ', entry.entryType);
    console.log('startTime:        ', entry.startTime);    // layout/render start
    console.log('renderTime:       ', entry.renderTime);   // (LCP/element-timing only)
    console.log('paintTime:        ', entry.paintTime);    // NEW in Chrome 145 — CPU paint done
    console.log('presentationTime: ', entry.presentationTime); // NEW — frame on screen
  }
});

observer.observe({
  type: 'largest-contentful-paint',  // has renderTime, paintTime, presentationTime
  buffered: true
});
observer.observe({
  type: 'element',       // element timing — same new fields
  buffered: true
});
observer.observe({
  type: 'long-animation-frame',  // LoAF entries — has presentationTime
  buffered: true
});
observer.observe({
  type: 'paint',  // first-paint / first-contentful-paint — has presentationTime
  buffered: true
});

references