<R/>

Crafting digital experiences

<R/>Rofiq.Full-Stack Product Engineer
AboutServicesWorkBlogRésuméContact
AboutServicesWorkBlogRésuméContact
Let's talk

One project slot open

Got something worth building? Let's make it real.

Start a project
<R/>Rofiq RahmanFull-Stack Product Engineer

Full-stack product engineering for teams that want the thing shipped, measured and maintainable.

Explore

AboutServicesWorkBlogRésuméContact

More

RésuméPrivacy policyUses — tools, hardware and setupRSS feed

Connect

© 2026 Rofiq Rahman. Crafted with Next.js.

Back to top
All articles

Performance

A performance budget that survives the deadline

Every team agrees the site should be fast, right up until the marketing tag goes in on a Thursday. Here is the setup that makes the budget hold without anyone having to be the villain.

Mr. Rofiq Rahman · Oct 9, 2026 · 8 min read

Lighthouse report with category scores, Core Web Vitals and a request waterfall

On this page

  1. Pick three numbers, not fifteen
  2. Measure the route, not the homepage
  3. Make it a pull request check
  4. Budget the third parties separately
  5. When to break the budget

Everyone agrees the site should be fast. Then a marketing tag goes in on a Thursday, nobody measures, and three months later you are in a meeting about why the site is slow.

The fix is not discipline. It is making the budget something the pipeline enforces, so no individual has to be the one who says no.

Pick three numbers, not fifteen

A budget nobody remembers is not a budget. Three numbers:

  • LCP under 2.0 s on a simulated mid-range Android over 4G.
  • Total JavaScript under 200 KB compressed, on the heaviest route.
  • CLS under 0.05.

That is it. If those three hold, the rest is usually fine.

Measure the route, not the homepage

The homepage is the page everyone optimises and almost nobody lands on. Run the check against your three highest-traffic routes from analytics. For the storefront I rebuilt last year, that was a category page, a product page and the cart — the homepage was fourth.

Make it a pull request check

- name: Lighthouse CI
  run: |
    npx @lhci/cli autorun \
      --collect.url=https://staging.example.com/products \
      --assert.assertions.largest-contentful-paint=error:2000

A failing check is a conversation at review time, which is cheap. The same conversation three months later costs a sprint.

Budget the third parties separately

First-party code rarely causes the regression. Tags do. Keep a list of every third-party script with its owner and its measured cost, and review it quarterly. Half of them will turn out to belong to a campaign that ended.

When to break the budget

Deliberately, in writing, with an expiry date. "We are shipping the chat widget for the launch; it costs 1.8 s on mobile; we remove or replace it by 1 March." That is a trade-off. Silently exceeding it is a regression.

The difference between a team that stays fast and one that does not is almost never knowledge. It is whether the slow version can reach production without anybody noticing.

  • #performance
  • #core web vitals
  • #next.js
  • #ci
Share

Keep reading

Related articles

Code editor with a file tree, an open component file and a terminal below

Next.js · Sep 24, 2026 · 11 min read

Server components changed how I structure a Next.js app

After six App Router projects, the folder structure I keep arriving at — and the three mistakes I made in the first two that cost me the most time.

#next.js#react#server components
Storefront product listing with a promotional banner and product grid

UX Engineering · Sep 7, 2026 · 6 min read

Your loading spinner is probably making things worse

Skeletons and spinners feel like good UX. Measured against perceived performance, most of the ones I have shipped made the page feel slower. What to use instead.

#ux#performance#react
Budgeting dashboard showing envelope budgets and a transaction list

Backend · Aug 16, 2026 · 5 min read

Storing money: integers, always

A short post about the one bug I refuse to debug twice, and the three places floating-point currency still sneaks into an otherwise careful codebase.

#backend#databases#money