Skip to content
Journal

Engineering

Performance Budgets Are a Design Decision

Headshot of Alex Fujimoto
Alex Fujimoto
January 9, 2024 · 3 min read

Most teams treat performance as a cleanup task. Design the site, build the site, run Lighthouse, panic, compress some images, ship. The result is a site that is exactly as slow as its heaviest idea, minus whatever the engineers could claw back at the end.

We do it backwards. The performance budget is agreed in the first week, before anyone opens Figma, and it sits in the project brief next to the brand guidelines. It carries the same authority.

The budget we start from

Every project negotiates its own numbers, but our default starting point for a marketing site looks like this:

{
  "budgets": [
    {
      "resourceSizes": [
        { "resourceType": "script", "budget": 150 },
        { "resourceType": "image", "budget": 400 },
        { "resourceType": "font", "budget": 100 },
        { "resourceType": "total", "budget": 800 }
      ],
      "timings": [
        { "metric": "largest-contentful-paint", "budget": 2000 },
        { "metric": "interactive", "budget": 3000 }
      ]
    }
  ]
}

Those sizes are kilobytes, compressed, on the initial route. They are not heroic numbers. They are achievable by any team that decides to achieve them, and they put you comfortably ahead of most of the sites you will compete with in a search results page.

Why designers need the budget first

A budget changes design conversations in concrete ways. When a designer knows fonts get 100 KB, the question shifts from "which six weights do we want" to "which two weights carry the system." That constraint usually improves the typography, because restraint usually improves typography.

Same with imagery. A full-bleed autoplay video hero is a beautiful thing, and it costs somewhere between one and four megabytes that the budget does not have. Sometimes the answer is yes anyway, and we cut elsewhere. That is fine. The point is that the trade is made consciously, by the whole team, in week two instead of week eleven.

The alternative, where design happens in a vacuum and engineering inherits the bill, produces the worst of both worlds: compromised visuals after the fact and a slow site anyway.

Enforcement or it did not happen

A budget that lives in a document is a wish. Ours lives in CI. Every pull request runs Lighthouse against the preview deployment, and a budget violation fails the build the same way a broken test does. Nobody argues with a red check. People argue endlessly with a slide from three months ago.

We also track the budget over time, because sites do not get slow in one commit. They get slow in forty commits that each added eleven kilobytes. The trend line matters more than any single reading.

What this bought us last year

The redesign we shipped for Northwind's e-commerce marketing pages came in under budget on every route, and their organic landing pages saw conversion improvements that their team attributes largely to speed on mid-tier Android devices. That is where the real internet lives, and it is invisible from a MacBook Pro on office wifi.

One more thing worth saying plainly: with the Core Web Vitals shakeup coming in March, responsiveness metrics are about to get more scrutiny, not less. Teams that have been coasting on a good FID score should look hard at their interaction latency now. We will write more about that when the change lands.

Set the budget first. Design inside it. Enforce it in CI. It is the least glamorous thing we do and one of the most valuable.

Building something this could apply to?

We take on a small number of flagship projects each quarter.

Start a project