← void

time

what javascript costs users, measured in milliseconds they will never get back

The browser is a performance machine. Given only HTML, it parses, layouts, and paints in under 100ms on modest hardware. The question is not whether your page can be fast. It can. The question is whether you will allow it to be.

the metrics

TTFB Time to First Byte

How long until the server responds with the first byte of HTML.

good< 200ms poor> 600ms

killerserver-side rendering frameworks that hydrate before responding

A static HTML file served from a CDN achieves < 20ms globally. A Next.js app with client hydration routinely achieves 400ms on a good day.
FCP First Contentful Paint

When the browser first renders something visible.

good< 1.8s poor> 3.0s

killerrender-blocking scripts in <head>

Every <script> tag without async or defer halts the parser. The browser waits. The user stares at white. This is load-order discipline. Most developers do not have it.
TBT Total Blocking Time

Sum of time the main thread was blocked, preventing user interaction.

good< 200ms poor> 600ms

killerJavaScript bundles over 50kb

Any task that runs longer than 50ms on the main thread is a long task. Long tasks block input. A 300kb React bundle parses and executes on the main thread. The user clicks. Nothing happens. They click again. Still nothing. This is your framework working as intended.
TTI Time to Interactive

When the page becomes reliably interactive.

good< 3.8s poor> 7.3s

killerhydration

Hydration is the process of taking server-rendered HTML and attaching JavaScript event listeners to it. The HTML already exists. The page already looks right. The user tries to click. Nothing happens — because the framework is still downloading its runtime and re-rendering what the server already rendered.
CLS Cumulative Layout Shift

Total visual instability as elements move after initial render.

good< 0.1 poor> 0.25

killerimages without dimensions, dynamically injected content, web fonts

The user is about to click a link. A font loads. Text reflows. The link moves 40px down. They click the ad instead. This is not an accident. This is what happens when you load content after the layout.
LCP Largest Contentful Paint

When the largest visible element finishes rendering.

good< 2.5s poor> 4.0s

killerhero images not preloaded, lazy-loaded above-the-fold content

The largest element is usually the hero image or the headline. If you lazy-load the hero image — the one that is immediately visible — you have optimized for a case that does not exist.

small sins with measurable consequences

on hydration: the framework community has responded to the hydration problem by inventing partial hydration, islands architecture, streaming SSR, resumability, and progressive hydration. these are all correct responses to a problem that did not exist before the frameworks that created them. the browser has shipped a fast, zero-kilobyte solution since 1996: HTML.
this page: system fonts. no javascript. no framework runtime. no hydration. TTFB governed by the CDN, not by a framework. TBT is zero. you are reading this in the time it takes another page to download its router.
estimated transfer: < 5kb — html + inline styles — js: 0 bytes