Web optimizations suddenly become important as your product grows. It loads images, videos, tables etc.
What could be the possible ways to optimize a ? I will completely guide you through the ways of optimization programmatically.SAAS dashboard
Reducing Assets Sizes
-
Compression: If your web page loads a bunch of images, you would probably need to compress them. Image Optim, FreeConvert are the best tools to compress images.
-
WebP/AVIF formats: We don't use png format for images on the web because webp gives us much smaller file size with similar visual quality. You can use CloudConvert to convert your images into webp file format.
-
Next.js/React:
is best for automatic image optimization. Learn morenext/image
// next.js example code
// source: https://nextjs.org/docs/app/api-reference/components/image
import Image from 'next/image'
<Image
src="/profile.webp"
width={500}
height={500}
alt="Picture of the author"
/>
Lazy Loading
It's about loading different parts of UI, sequentially, or even dynamically.
Next.js allows us to use React Lazy and Suspense in a composite way. Which is .next/dynamic
import { Suspense } from "react";
import dynamic from 'next/dynamic'
// loads directly when used
const ComponentA = dynamic(() => import('../components/A'))
// ssr: false allows us to load the component directly on the client side
const ComponentB = dynamic(() => import('../components/B'), { ssr: false})
// page.js
export default function Page() {
return (
{ /* using suspense to lazy load on the client side with fallback ui */ }
<Suspense fallback={<p>Loading...</p>}>
<div>Component B:</div>
{ /* while ComponentB lazy load itself */ }
{ /* but only when the condition is met */ }
{someState && <ComponentB />}
</Suspense>
);
}
// Above example shows the beset hierarchical way to lazy load entire component
The interesting thing it offers is loading.js. You can wrap your entire route in a custom loading state by adding a new file along the .page.js
Optimize API calls
- fetch: For the server components, you should be using
as here. Here you can pass options asfetchor{ cache: "force-cache" | "no-store" }
const data = await fetch('https://api.vercel.app/blog')
const posts = await data.json()
const API = "https://jsonplaceholder.typicode.com/todos/";
fetch(API, { cache: "no-cache" }) // it means don't cache anything, fetches resources on every single request
fetch(API, { cache: "force-cache" }) // it caches the page on the first render
fetch(API, { cache: "force-cache", next: { revalidate: 60 } }) // same, but revalidate after the interval
- TanStack Query/React: For the client components, you should be using some client side resource fetching library. For example, in tanstack query,
import axios from "axios";
import { useQuery } from "@tanstack/react-query";
const fetchPosts = async () => {
// use axios for fetching
const { data } = await axios.get("/api/posts");
return data;
};
const {
isPending, // boolean (true|false)
isError, // boolean (true|false)
data, // contains the JSON data
error // instanceof Error
} = useQuery({
queryKey: ["posts"],
queryFn: fetchPosts,
staleTime: 60000, // re-validation
});