May 8, 2025
The size of your Next.js application's client-side bundle directly impacts your website’s loading speed, user experience, and ad revenue. A common mistake is embedding large JavaScript/JSON objects or Base64-encoded images in the client-side code. This practice can balloon bundle sizes, slow page loads, and ultimately hurt your product’s performance.
In this article, we’ll highlight why embedding large data in the client code is problematic, showcase examples of bad practices, and provide actionable solutions to keep your Next.js projects optimized.
A common mistake in Next.js projects is storing significant datasets directly in client-side code. Consider this example:
'use client';
const usersDatabase = [
{ id: 1, name: 'John Doe', email: '[email protected]' },
{ id: 2, name: 'Jane Doe', email: '[email protected]' },
// Imagine this list has tens of thousands of entries...
];
export default function UserList() {
return (
<div>
{usersDatabase.map((user) => (
<p key={user.id}>{user.name}</p>
))}
</div>
);
}
Why it’s bad:
Another pitfall is embedding large images directly in the client-side JavaScript.
'use client';
const imageData = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAoAAAAHgCAYAAAA..."; // Truncated for brevity
export default function DisplayImage() {
return <img src={imageData} alt="Example" />;
}
Why it’s bad:
Sometimes, developers embed large configuration objects or API keys directly in the client code.
'use client';
const appConfig = {
apiUrl: "https://api.example.com",
settings: {
theme: "dark",
features: {
experimental: true,
// Contains deeply nested settings
},
},
};
export default function ConfigInfo() {
return <pre>{JSON.stringify(appConfig, null, 2)}</pre>;
}
Why it’s bad:
Instead of embedding datasets in your client-side code, fetch them dynamically using server-side APIs.
'use client';
import { useState, useEffect } from 'react';
export default function UserList() {
const [users, setUsers] = useState([]);
useEffect(() => {
fetch('/api/users') // Fetch data from a server API
.then((response) => response.json())
.then((data) => setUsers(data));
}, []);
return (
<div>
{users.map((user) => (
<p key={user.id}>{user.name}</p>
))}
</div>
);
}
Download our service guide to understand how we can help you optimise your site speed
Benefits:
Instead of embedding Base64 images, serve them through a Content Delivery Network (CDN).
'use client';
export default function DisplayImage() {
const imageUrl = "https://cdn.example.com/images/example.png";
return <img src={imageUrl} alt="Example" />;
}
Benefits:
Store large configuration objects and sensitive data securely on the server. Use environment variables and API endpoints to retrieve necessary configurations.
// Server-side code (e.g., /api/config)
export default function handler(req, res) {
res.status(200).json({
apiUrl: process.env.API_URL,
settings: { theme: "dark", features: { experimental: true } },
});
}
'use client';
import { useEffect, useState } from 'react';
export default function ConfigInfo() {
const [config, setConfig] = useState(null);
useEffect(() => {
fetch('/api/config')
.then((response) => response.json())
.then((data) => setConfig(data));
}, []);
return <pre>{JSON.stringify(config, null, 2)}</pre>;
}
Benefits:
Embedding large data or media directly in the client-side code of your Next.js project is a recipe for poor performance and slow user experiences. By leveraging server-side APIs, CDNs, and proper configuration management, you can significantly reduce your bundle size, improve load times, and ensure a smoother experience for your users.
Remember, performance optimization isn’t just about speed—it’s about delivering value faster, keeping users engaged, and maximizing your website’s potential.
Our experts in Next.js performance can help you improve the speed and performance of your app.Get in touchto learn how we can help.
Download our service guide to understand how
we can help you optimise your site speed