Making a Next.js site fast: the fixes that moved Core Web Vitals on techdome.io
Hero images that wait for JavaScript, an embedded scheduler that blocked the page, oversized images and bloated page data: the real fixes behind our site's performance work, and a checklist for yours.


This website, techdome.io, is built with Next.js and React. Over several rounds of work we have improved how fast it loads and responds, and the fixes were rarely clever. Most were one slow thing, found and removed.
This post lists what we changed and why each change helps, then gives a checklist you can run against your own app. The measures behind it are the Core Web Vitals: Largest Contentful Paint (LCP), Interaction to Next Paint (INP) and Cumulative Layout Shift (CLS). Total Blocking Time (TBT) is the lab measure that stands in for responsiveness when you test with a tool like Lighthouse.
What we changed on techdome.io
1. The hero no longer waits for JavaScript
An animated hero that starts invisible and fades in after the page's JavaScript loads delays the largest element on the screen, which is exactly what LCP measures. We changed the hero and the shared animation components so the server-rendered markup is visible from the first paint, and removed a hero opacity delay. The animation still runs; it just no longer gates what the visitor sees.
2. An embedded scheduler was blocking the page
Our contact page embeds a third-party scheduler. The fix for it records about 7.2 seconds of blocking time. We replaced the embed's first paint with a lightweight placeholder that shows immediately while the real embed loads behind it, so the page is usable first and the heavy script arrives afterwards.
3. Analytics moved out of the way
Analytics scripts are useful and not urgent. We deferred them, so they load after the page is interactive and compete less with what the visitor came for. They also stay off until the visitor gives consent.
4. Images were the biggest bytes
We resized images to at most 2,000 pixels wide and recompressed them, keeping JPEGs as JPEGs and PNGs as PNGs, which took the images folder from about 24 MB to about 10 MB. On one page, an image was being requested at 3,840 pixels wide, so we capped its sizes at 1,280 pixels.
5. The home page was carrying data it did not show
A Next.js page sends the data its components use to the browser. Our home page was passing full records to sections that only render small cards. Passing card-sized data instead cut the embedded page data from 447 KB to 324 KB, and the HTML from 958 KB to 834 KB.
6. Animations on the compositor
Animating transform and opacity lets the browser move a finished layer on the GPU, while animating layout properties makes it recalculate the page on every frame. We rebuilt effects around transform and opacity, and respect the visitor's reduced-motion setting.
A checklist for your Next.js app
- Find your LCP element and make sure it is in the first HTML, not created by client JavaScript.
- Use the framework's image component with a correct
sizesvalue, and compress the source files. - Load fonts through the framework's font loader so text shows without a layout jump.
- Load third-party scripts with the framework's script strategy, and show a placeholder while heavy embeds load.
- Keep client components for what is interactive, and leave static content in server components.
- Pass components only the fields they render.
- Animate transform and opacity, not width, height or position.
- Measure on a mid-range phone with throttling, and watch real-user data, not only lab scores.
Monorepos
The same rules apply in a monorepo, with one addition: keep shared packages light. A heavy dependency in a package that every app imports lands in every bundle, so one team's convenience becomes everyone's slow page.
How this looks at Techdome
Performance is part of how we build, not a final polish. In the Blueprint, Week 7 is reserved for security review, an accessibility audit and load testing before launch. Our offline-first clinic application is a Next.js progressive web app, described in the case study. Our web development topic page collects the rest.
Related reading
- The Techdome Blueprint: where performance testing sits in a build.
- Production n8n: patterns that keep automation from failing quietly
- Building AI agents that hold up in production
- API testing explained: types, what to automate, and tools
Takeaways
- Make the largest element visible in the first server-rendered HTML.
- Show a lightweight placeholder while heavy third-party embeds load, and defer analytics.
- Compress images at the source and give the image component honest sizes.
- Send the browser only the data it renders, and animate transform and opacity.
- Measure real-user data on real devices, and fix the biggest thing first.
Have a project like this? Talk to our engineers.








