Improving INP: finding the long tasks that make a page feel slow
INP is the metric that exposes how much JavaScript you shipped. A page can load in a second and still feel broken when tapped.
Cut bundle size by analysing what is actually in the bundle, splitting rarely-used code behind dynamic imports, replacing heavy dependencies with lighter or native alternatives, moving logic to the server where the framework allows it, and enforcing a size budget in CI so regressions are caught at review time.
| Heavy | Lighter alternative | Typical saving |
|---|---|---|
| moment | date-fns, dayjs, or Intl | 60–70 KB |
| lodash (full) | Per-method imports or native | 60+ KB |
| Full icon packages | Individual icon imports | Varies, often large |
| axios | fetch | ~15 KB |
| Full charting library | Lazy-loaded or lighter library | 100 KB+ |
| Full UI kit | Headless primitives + your own styles | Varies |
Before adding any dependency, check its size and whether it tree-shakes. A five-second check at install time is worth more than a bundle-reduction project a year later.
// Load the editor only when the user opens it
const RichTextEditor = dynamic(() => import("@/components/rich-text-editor"), {
loading: () => <EditorSkeleton />,
ssr: false,
});
// Load a chart library only on the route that renders charts
const Chart = dynamic(() => import("@/components/chart"));The number that matters is first-load JavaScript on your most-visited route, on mobile, compressed. Track that single figure over time and most of the discipline follows from it.
Under about 170KB compressed for first-load JavaScript on content routes is a reasonable target. Application dashboards run higher, but the number should be deliberate rather than accidental.
They reduce transfer size but not parse and execution cost, which is what hurts on slow devices. 200KB of compressed JavaScript still has to be parsed and run.
Only for ES modules with no side effects. CommonJS packages, side-effectful imports and namespace imports all defeat it. Check the package's module format before assuming.
It does not affect the browser, but it affects cold start times in serverless environments. Keep function bundles lean for latency-sensitive endpoints.
ROVQIX Engineering
Engineering team, ROVQIX
The ROVQIX engineering team builds and maintains web platforms, APIs and infrastructure for clients across SaaS, ecommerce and enterprise. These notes come out of real production work — deploys, incidents, migrations and audits.
ROVQIXdesigns and builds production web platforms — Next.js front ends, Node.js APIs and the infrastructure behind them. Tell us what you're building and we'll scope it with you.
INP is the metric that exposes how much JavaScript you shipped. A page can load in a second and still feel broken when tapped.
Performance work that happens once decays within two quarters. A budget makes it a constraint every pull request has to respect.
Server components are not 'SSR with extra steps'. They change what code ships to the browser at all — and that changes how you structure a codebase.
No spam. Just the occasional case study and craft breakdown.