Diagnostics

Performance stats for this page

Measured live in your browser with the Performance Timeline API — no third-party analytics, no tracking. These observers start when this route mounts and only count entries recorded afterwards, so the values describe this page alone rather than your whole browsing session (the usual Web Vitals behaviour, where CLS keeps accumulating across route changes). Every other page carries the same strip of its own numbers at the bottom.

This page was a full document load, so LCP, FCP and TTFB are available.

LCP

measuring

—

Largest Contentful Paint

When the biggest element of this page finished rendering.

CLS

good

0.000

Cumulative Layout Shift

How much this page's layout jumped, counted from the moment it mounted.

INP

measuring

—

Interaction to Next Paint

Slowest interaction response on this page — click or scroll something to measure it.

FCP

measuring

—

First Contentful Paint

First moment anything was painted.

TTFB

measuring

—

Time to First Byte

Server response speed for the document.

RENDER

measuring

—

Route render time

Time from this route mounting to its first painted frame.

Transferred bytes

Total 0 KB across 0 requests.

TypeRequestsSize

Note on CLS: standard Web Vitals reports CLS per *session*, so it keeps growing across client-side route changes and one bad shift on an earlier page shows up here — that is why the same page could read 0.003 on one visit and far higher on another. This page now scopes every observer to the mounted route, so the CLS above only counts shifts that happened on this page. Note that browser-level surfaces (translate bars, extensions, autofill) can still contribute a shift while you are on the page.

Tips · how these numbers were earned

What I did to make this site render this fast

  1. 01

    Server-rendered HTML, no loading spinners

    Every page is streamed as complete HTML from the edge, so the first byte already contains the text you came to read. No client-side data fetch stands between you and the content.

    TTFB · FCP · LCP

  2. 02

    Self-hosted variable fonts, preloaded

    Space Grotesk and JetBrains Mono are served as same-origin, immutable woff2 variable fonts and preloaded in the document head — no Google Fonts stylesheet, no extra DNS/TLS handshake to a third party. font-display: swap keeps text visible while they arrive.

    LCP · CLS

  3. 03

    Latin-only font subsets

    Only the latin and latin-ext unicode ranges ship, cutting font bytes by roughly two thirds versus the full family.

    Transferred bytes

  4. 04

    No images in the critical path

    The design is typography, borders and CSS gradients only — the largest paint is text, which is the cheapest possible LCP element.

    LCP

  5. 05

    Off-screen sections skip rendering

    Below-the-fold sections use CSS content-visibility: auto with a reserved contain-intrinsic-size, so the browser skips their layout and paint until you scroll near them — without ever shifting the page.

    INP · CLS

  6. 06

    Route-level code splitting

    Each route ships its own chunk. The résumé, this diagnostics page and the chat assistant are separate bundles, so the home page never downloads code it does not use.

    LCP · INP

  7. 07

    The chat assistant loads last

    The Groq-powered assistant is lazy-imported during browser idle time, after the page is interactive, so it never competes with first render. web-vitals itself is dynamically imported on this page only.

    INP · Transferred bytes

  8. 08

    First load no longer waits for animation JS

    Entrance animations used to be driven by the motion library, which meant the hero text stayed invisible until React hydrated — a slow first LCP. They are now plain CSS keyframes plus a ~20-line IntersectionObserver, so the server HTML paints and animates immediately and the animation library is off the first-load path entirely.

    FCP · LCP

  9. 09

    Skeletons instead of pop-in

    Anything that mounts late — the chat launcher, lazy route chunks — first renders a shimmering skeleton in exactly the final box size. You see structure instantly and nothing jumps when the real component arrives.

    CLS · perceived speed

  10. 10

    Counters render their final value on the server

    Impact metrics are server-rendered at their end value and only count up once scrolled into view, so the first paint never shows a placeholder 0 or resizes as digits are added.

    LCP · CLS

  11. 11

    Reserved space everywhere

    Metrics, cards and the timeline have fixed layout boxes and animate with transform/opacity only — never width, height or top — so nothing reflows mid-animation.

    CLS

  12. 12

    Motion respects the OS

    All animations honour prefers-reduced-motion and run on the compositor, keeping the main thread free for your interactions.

    INP

  13. 13

    Intent preloading + idle prefetch

    Hovering a link preloads that route; after first paint the remaining routes, the roadmap, the interview platform and the CV PDF are prefetched during idle time. Second visits render from cache instantly.

    Repeat-visit LCP

  14. 14

    Long-lived cache headers

    Hashed assets are immutable for a year, static tool pages and the PDF cache for a day with stale-while-revalidate, documents revalidate in the background, and the chat API is no-store.

    TTFB

  15. 15

    Tight, tree-shaken dependencies

    No UI framework bloat, no analytics, no tracking scripts, no polyfill bundles. Icons are imported individually and everything ships as modern ES modules.

    Transferred bytes · INP