Home / Hardware and Performance / Performance Monitor Widget

Performance Monitor Widget in JavaScript, Free with Live Demo

Free performance monitor in plain JavaScript. Measure LCP, CLS, INP, FCP, TTFB, long tasks and FPS live with PerformanceObserver, and trigger issues to learn.

Open live demoDownload HTML fileView code on GitHub
Performance Monitor Widget JavaScript project: a live panel for Core Web Vitals on any page

Runs on: PerformanceObserver. All metrics: Chrome and Edge. Safari and Firefox support FCP, TTFB and LCP (Firefox and Safari 26+), with INP and CLS in the newest versions or not at all.

What is the Performance Monitor Widget?

Watch this page's Core Web Vitals update live: loading speed, layout shifts and how fast it responds to clicks. Buttons let you cause a layout shift or a slow task so you can see exactly how the scores react.

Every number comes from PerformanceObserver. CLS groups layout shifts into session windows, INP takes the slowest interaction, and each value is rated with Google's official good and poor thresholds.

Good for

  • SEO and site speed audits
  • Debugging slow pages
  • Teaching Core Web Vitals
  • Adding a speed panel to your own site

What this project does

How it works

  1. Observe entriesA PerformanceObserver subscribes to each entry type. buffered: true replays what happened before the script ran.
  2. Compute the metricCLS groups shifts into session windows. INP takes the slowest interaction. LCP takes the last large paint.
  3. Rate itEach value is compared with the official thresholds, for example LCP is good under 2.5 seconds.

The key JavaScript

This is the heart of the project. The full file has the rest, including the screen layout and error handling.

new PerformanceObserver((list) => {
  const last = list.getEntries().at(-1);
  report("LCP", last.startTime);                        // good under 2500 ms
}).observe({ type: "largest-contentful-paint", buffered: true });

let cls = 0;
new PerformanceObserver((list) => {
  for (const e of list.getEntries()) if (!e.hadRecentInput) cls += e.value;
  report("CLS", cls);                                   // good under 0.1
}).observe({ type: "layout-shift", buffered: true });

new PerformanceObserver((list) => {
  for (const e of list.getEntries()) if (e.interactionId) inp = Math.max(inp, e.duration);
}).observe({ type: "event", durationThreshold: 16, buffered: true });

How to use it

  1. Click Download HTML file above.
  2. Open the file in a code editor, like VS Code.
  3. Run it from a local server with npx serve . so the camera, microphone and AI features are allowed.
  4. Change the text and colors, then upload it to GitHub Pages, Netlify or your own site. It is one file with no build step.

Questions people ask

What are good Core Web Vitals scores?

LCP under 2.5 seconds, CLS under 0.1 and INP under 200 milliseconds count as good.

Why is INP empty at first?

INP measures interactions, so it needs you to click or type something first.

Can I add this to my own site?

Yes. Copy the observer code and send the values to your analytics instead of showing them.

More Hardware and Performance projects