Back to all writing

PERFORMANCE/4 MIN READ

Finding a frontend performance bottleneck

Network waterfalls, rendering traces, and measurements that make a performance change reproducible.

On VAULT, Largest Contentful Paint moved from roughly 3 seconds to 800 milliseconds, and the JavaScript bundle from 180 KB to 60 KB. For another application, the first step is to find its own bottleneck. Start with a specific route, a repeatable baseline, and a browser trace.

Decide what “fast” means for the task

A content page, a search interface, and a dashboard have different critical paths.

  • On a content page, the reader needs the main content to appear.
  • In search, the user needs immediate feedback and a useful result.
  • In a dashboard, the first meaningful view matters more than every secondary panel being ready.

Core Web Vitals help describe loading, responsiveness, and visual stability. They do not replace understanding the user’s task. Pair them with a small number of product-specific measurements.

Find the actual bottleneck

Start with a network waterfall and a browser performance trace. Look for serial requests, expensive JavaScript evaluation, long rendering tasks, and resources competing with the main content.

Do not reach for memoization before checking whether the application is shipping a large dependency that the initial screen does not use. Do not add a cache before understanding whether it will serve the right data at the right time.

A useful investigation records:

  1. The route and user flow being measured.
  2. The device and connection conditions.
  3. Whether the cache is warm or cold.
  4. The baseline and the proposed change.
  5. The new result, including regressions elsewhere.

This makes a performance claim reproducible rather than anecdotal.

Check the JavaScript cost

JavaScript has costs beyond transfer size. The browser still has to parse, evaluate, and often hydrate it.

For a content-led site like this one, static HTML handles most of the work. Interactive islands are reserved for features that need them, such as searching articles or opening the command menu. The rest of the page stays readable without a client-side application booting first.

Other useful questions:

  • Can a heavy editor load only when someone opens it?
  • Does an entire icon library end up in the bundle?
  • Are images sized for where they are displayed?
  • Can independent requests happen concurrently?
  • Is client state duplicating data that a query cache already owns?

Handle loading and failure states

A skeleton can communicate structure, but a skeleton that remains forever is just a different kind of blank page. Show errors, provide a retry path, and distinguish “no results” from “still loading.”

For streaming experiences, the first useful response often matters more than the time to the final token. That does not mean hiding total completion time; it means measuring both.

Track regressions

Choose budgets that match the product. Track critical route bundles and watch real-user metrics where available. A budget is most useful when it catches a regression close to the change that introduced it.

Questions or feedback?

Email me about this article

Gate of Gilvex

Survive 30 seconds. Avoid the blades and transform to dash. Near misses earn points.

Time
30.0s
Score
0
Shields
3
This arcade game needs a browser with Canvas support.

Survive 30 seconds.

Loading…

Best 0

WASD / arrows to move Space to dash

Options

Move with WASD, arrows, or the touch pad. Space or Dash transforms you briefly.

Your cyan core is the hitbox. Near misses earn points.

P pauses. Escape exits.