I recently shipped datecalc.xyz — a date calculator tool built with Next.js 14, TypeScript, Tailwind CSS, and date-fns. The site does what it says: calculate differences between dates, add/subtract durations, find day-of-week, and more.
The goal was simple, but the constraint was strict: score as high as possible on PageSpeed Insights before writing a single line of marketing copy.
Here's what actually moved the needle.
The render-blocking font trap
My first build loaded Google Fonts the naive way — a in _document.tsx. PageSpeed flagged it immediately as render-blocking. The fix: switch to next/font/google with display: 'swap' and preload: true. Next.js inlines the @font-face declaration at build time and handles preloading automatically. Gone from the waterfall.
CLS was the sneaky one
I had a layout shift score of 0.14 — enough to tank Performance. The culprit: a container div that rendered at one height server-side and a slightly different height after hydration, because a conditional UI element wasn't included in the initial render. Fix: always render the element, use visibility: hidden on the conditional part instead of conditionally mounting it. CLS dropped to 0.
Static generation did the heavy lifting
Every route on datecalc.xyz is statically generated at build time via generateStaticParams. There's no server computation at request time, no API calls, no spinners. The HTML lands in the browser fully formed. This is the single biggest performance lever Next.js gives you — and most people leave it on the table.
TBT: the long task problem
Total Blocking Time was my last remaining issue. I had a date computation running on every keystroke inside a useEffect with no debounce. A 16ms calculation becomes a UX problem at scale. Wrapping it in a 150ms debounce brought TBT to 0.
Final scores: Performance 98 · Accessibility 100 · Best Practices 100 · SEO 100.
None of this required exotic tooling. Just Next.js doing what it's designed for — if you let it.
The site is live at datecalc.xyz if you want to poke at it.
Top comments (0)