Skip to content
Dashboard

Guide to fast websites with Next.js: Tips for maximizing server speeds and minimizing client burden

Tinloof Co-founder

Tinloof Co-founder Seif Ghezala gives insights into how his team measures website speed with best practices to make faster websites.

Link to headingThe basics of site speed: Measuring data correctly

Vercel Speed Insights

Learn how to get a detailed view of your website's performance metrics to help facilitate informed decisions on optimization.

Get Started

Link to headingHow to speed up server response: Make use of Next.js’ rendering toolbox

Link to headingWhen possible: Pre-render the entire page

Link to headingElse: Partial Prerender

Link to headingFinal resort: Render a loading shell while waiting for the final response

Link to headingCache fetch requests for fast server responses when using loading spinners

app/page.tsx
export default function Home() {
// The CMS data is guaranteed to be fresh every 2 minutes
const cmsData = await fetch(`https://...`, { next: { revalidate: 120 } });
return <h1>{cmsData.title}</h1>
}

app/page.tsx
export default function Home() {
// The CMS data is cached until the tag is revalidated
const cmsData = await fetch(`https://...`, { next: { tags: ['landing-page']);
return <h1>{cmsData.title}</h1>
}

app/api/revalidate/route.ts
import { revalidateTag } from 'next/cache';
import { NextRequest, NextResponse } from 'next/server';
export async function POST(req: NextRequest): Promise<NextResponse> {
const secret = req.nextUrl.searchParams.get('secret');
const tag = req.nextUrl.searchParams.get('landing-page');
if(!tag || !isValid(secret)) {
return NextResponse.json({ status: 400});
}
return revalidate(tag);
}

Link to headingHow to speed up the page render: Minimize client burden

Link to headingReduce the JavaScript bundle size and minimize the impact of hydration

Link to headingReduce the impact of client components on page speed

Link to headingOnly use client components when necessary

Link to headingPlace client components in the leaves of the page tree

Link to headingBe mindful of third-party dependencies’ bundle sizes

Link to headingLazy-load client components when possible

Link to headingEfficiently load third-party scripts

Link to headingHow to load fonts more efficiently

Link to headingHow to load images more efficiently

Link to headingHow to load videos more efficiently

import { preload } from "react-dom";
import { unstable_getImgProps as getImgProps } from "next/image";
type Props = {
playbackId: string;
loading: "lazy" | "eager";
resolution: "SD" | "HD";
};
export default function MuxVideo({ playBackId, loading, loading }: Props) {
const mp4Url = `https://stream.mux.com/${playbackId}/${
resolution === "SD" ? "medium" : "high"
}.mp4`;
const webmUrl = `https://stream.mux.com/${playbackId}/${
resolution === "SD" ? "medium" : "high"
}.webm`;
// Use `getImgProps` to convert the video poster image to WebP
const {
props: { src: poster },
} = getImgProps({
src: `https://image.mux.com/${playbackId}/thumbnail.webp?fit_mode=smartcrop&time=0`,
alt: "",
fill: true,
});
// Preload the poster when applicable
if (loading === "eager") {
preload(poster, {
as: "image",
fetchPriority: "high",
});
}
return (
<video
autoPlay
playsInline
loop
controls={false}
muted
preload="none"
>
<source src={mp4Url} type="video/mp4" />
<source src={webmUrl} type="video/webm" />
</video>
);
}

'use client';
import Image from 'next/image';
import { useEffect, useState } from 'react';
import useInView from '~/hooks/useInView';
import Video, { VideoProps } from './Video';
export default function LazyLoadedVideo(props: VideoProps) {
const { ref, inView } = useInView({ triggerOnce: true });
return (
<>
{!inView ? (
<Image
ref={ref as React.RefObject<HTMLImageElement>}
alt={'Video poster'}
src={props.poster ?? ''}
className={props.className}
style={props.style}
loading={'lazy'}
layout="fill"
/>
) : (
<Video {...props} />
)}
</>
);
}

Link to headingHow to reduce the HTML document size

Link to headingUse virtualization

Link to headingHow to speed up user interactions

Link to headingThe importance of a performant website

Want to talk to an expert?

Brainstorm with our team about your unique use case of Next.js.

Send us a message