Introduction
After building my portfolio website using Next.js and Tailwind CSS, I wanted to make sure it wasn’t just visually appealing — but also fast, discoverable, and SEO-friendly.
In this blog, I’ll walk you through the exact steps I took to optimize my portfolio for both SEO and performance, ensuring it loads fast and ranks better on Google.
Step 1: Using Next.js Built-in Optimizations
Next.js already gives you a head start with features like:
- Automatic code splitting — loads only what’s needed for each page.
- Server-side rendering (SSR) for better SEO indexing.
- Static site generation (SSG) for faster response times.
I used SSG for all my pages so that search engines can easily crawl them and the site loads almost instantly from Vercel’s CDN.
export async function getStaticProps() {
// Fetch blog data or project details at build time
return {
props: {
/* data */
},
};
}
Step 2: Adding a Sitemap and Robots.txt
One of the most overlooked SEO steps is providing search engines a roadmap of your website. So I generated a sitemap.xml automatically using the next-sitemap package.
npm install next-sitemap
Then I created a simple config file (next-sitemap.config.js):
/** @type {import('next-sitemap').IConfig} */
module.exports = {
siteUrl: "https://hitanshukhandelwal.com", // Replace with your domain
generateRobotsTxt: true, // (optional) generate robots.txt
sitemapSize: 5000, // optional, splits sitemap if too many URLs
changefreq: "weekly", // optional, how often pages change
priority: 0.7, // optional, default priority for pages
robotsTxtOptions: {
additionalSitemaps: ["https://hitanshukhandelwal.com/sitemap.xml"],
},
};
This ensures:
- Responsive image sizing
- Lazy loading by default
- Automatic WebP conversion
Step 3: Optimizing Images with next/image
Images can easily slow down a site if not optimized. Using the built-in next/image component helped me automatically handle:
- Responsive image sizing
- Lazy loading by default
- Automatic WebP conversion
import Image from "next/image";
<Image
src="/images/projects/algokeep-preview.png"
alt="AlgoKeep Project Preview"
width={800}
height={600}
priority
className="rounded-xl"
/>
Step 4: Implementing Lazy Loading & Dynamic Imports
For components not visible immediately (like project carousels or animations), I used dynamic imports to load them only when needed.
import dynamic from "next/dynamic";
const Animation = dynamic(() => import("@/components/animation"), {
ssr: false,
loading: () => <p>Loading...</p>,
});
This strategy reduced my initial JavaScript bundle size and improved First Input Delay (FID) and Total Blocking Time (TBT).
Step 5: SEO Metadata & Open Graph Tags
Search engines and social platforms love structured metadata.
I used Next.js's <Head> from next/head to add custom meta tags per page.
import Head from "next/head";
<Head>
<title>Hitanshu Khandelwal | Portfolio</title>
<meta
name="description"
content="Software Developer building fast, accessible, and AI-powered web experiences."
/>
<meta property="og:title" content="Hitanshu Khandelwal | Portfolio" />
<meta property="og:image" content="/meta-thumbnail.png" />
<meta name="twitter:card" content="summary_large_image" />
</Head>
Each blog post and project page also has its own title, description, and preview image, improving click-through rates from Google and social shares.
Step 6: Auditing with Lighthouse
After deployment, I ran my site through Google Lighthouse and checked for:
- Performance: Aiming for 90+
- Accessibility: Ensuring semantic HTML and alt text
- Best Practices: Avoiding oversized bundles
- SEO: Proper tags and link structure
This helped me spot a few issues like unused JavaScript and unoptimized image dimensions, which I quickly fixed.
Step 7: Deploying on Vercel (and Using Analytics)
Finally, I deployed everything on Vercel, which automatically optimizes builds for static assets, compression, and caching.
I also enabled Vercel Analytics to monitor page load times and Core Web Vitals in real time. It’s a great way to track performance without adding third-party scripts.
Results
After implementing all these optimizations:
- PageSpeed score: 98/100
- Lighthouse Performance: 96+
- SEO score: 100
Bounce rate: Dropped by ~20% after improving load time
