No loading spinners for the first view
In plain React, data loads *after* the page appears: spinner, fetch, re-render. In the App Router, components are Server Components by default: they run on the server, can be async, read the database directly, and send finished HTML. Their code never reaches the browser.
async components and secrets
import { getDishes } from "@/lib/data";
async function DishCount() {
const dishes = await getDishes();
return <p>We serve {dishes.length} dishes today.</p>;
}
export default async function Page() {
const dishes = await getDishes();
const cheapest = [...dishes].sort((a, b) => a.price - b.price)[0];
return (
<section>
<h1>Today</h1>
<DishCount />
<p>Cheapest: {cheapest.name} (Rs {cheapest.price})</p>
</section>
);
}- Server Components can't use state, effects or event handlers — there's no browser where they run.
- They *can* render Client Components and pass them serialisable props (strings, numbers, plain objects).
- Result: less JavaScript sent to phones, faster first loads, and data fetching without waterfalls of useEffect.