前言

我们用CRA(create-react-app)写的React应用,是纯客户端渲染(CSR)。服务器只返回一个空<div id="root"></div>和一堆JS,浏览器先白屏,下载JS、执行完才显示内容。问题:

  • 首屏慢:JS越大越慢。
  • SEO差:爬虫抓不到内容,因为要等JS执行。
  • 社交分享卡片难看:分享链接时,预览图标题描述都是空的。

Next.js是React的服务端渲染框架。它能在服务器端提前生成HTML,用户直接看到内容,然后再“激活”交互。而且它还能静态生成、服务端渲染、甚至当后端用。今天我们就来上手Next.js,解决“白屏+SEO”两大痛点。

一、Next.js解决了什么?一张图看懂

  • CSR(CRA):浏览器请求 → 返回空HTML → 下载JS → 执行 → 显示内容。用户等得花儿都谢了。
  • SSR(Next.js):浏览器请求 → 服务器执行React,生成完整HTML → 返回给浏览器 → 显示内容 → 下载JS绑定事件。用户立刻看到内容,体验好。
  • SSG(静态生成):构建时就生成HTML,访问时直接返回,最快。

Next.js同时支持SSR、SSG、CSR,你能根据页面特性选择不同渲染方式。

二、5分钟上手Next.js

npx create-next-app@latest my-app
cd my-app
npm run dev

打开http://localhost:3000。目录结构:

  • pages/:路由系统,pages/index.js就是首页,pages/about.js就是/about
  • public/:静态资源。
  • styles/:CSS。

三、路由:不用react-router,文件即路由

pages下创建文件就是路由。

  • pages/index.js/
  • pages/about.js/about
  • pages/blog/[slug].js/blog/hello-world(动态路由)

页面链接用Link组件:

import Link from 'next/link';

export default function Home() {
  return (
    <Link href="/about">关于我们</Link>
  );
}

四、预渲染的三种模式

1. 静态生成(SSG):在构建时生成HTML

适用于博客文章、产品页、帮助文档等不常变的内容。速度最快,可放CDN。

// pages/blog/[id].js
export async function getStaticPaths() {
  // 告诉Next.js有哪些动态路径需要生成
  const paths = await fetchPosts().then(posts => posts.map(p => ({ params: { id: p.id } })));
  return { paths, fallback: false };
}

export async function getStaticProps({ params }) {
  const post = await fetchPost(params.id);
  return { props: { post } };
}

export default function Post({ post }) {
  return <div>{post.title}</div>;
}

构建时next build会生成每个文章的HTML。

2. 服务端渲染(SSR):每次请求时在服务器生成HTML

适用于用户个性化页面、实时数据页面。

// pages/profile.js
export async function getServerSideProps(context) {
  const user = await fetchUser(context.req.cookies.token);
  return { props: { user } };
}

export default function Profile({ user }) {
  return <div>欢迎 {user.name}</div>;
}

每次访问都会调用getServerSideProps,所以可以获取请求上下文(cookies、headers等)。

3. 客户端渲染(CSR):就跟普通React一样

适用于仪表盘、后台管理等不需要SEO的部分。

import { useEffect, useState } from 'react';

export default function Dashboard() {
  const [data, setData] = useState(null);
  useEffect(() => {
    fetch('/api/dashboard').then(r => r.json()).then(setData);
  }, []);
  if (!data) return <div>加载中...</div>;
  return <div>{data.chart}</div>;
}

五、API Routes:把你的Next.js当后端用

pages/api下创建文件,就能写服务端代码,相当于一个小型Node后端。

// pages/api/hello.js
export default function handler(req, res) {
  res.status(200).json({ message: 'Hello Next.js!' });
}

访问/api/hello得到JSON。你可以在这里连接数据库、验证请求、调用第三方API。这样就不需要单独起一个后端服务了。

六、内置优化:你啥都没干,它帮你做了

  • 图片优化:用next/image自动压缩、懒加载、生成webp。

    import Image from 'next/image';
    <Image src="/logo.png" width={200} height={100} alt="Logo" />
  • 字体优化:自动内联CSS,减少布局偏移。
  • Script优化next/script控制加载时机(beforeInteractive、afterInteractive、lazyOnload)。
  • 静态资源缓存:会为文件生成hash,永久缓存。

七、实战:从CRA迁移到Next.js的收益

假设一个博客站:

  • CRA:首屏加载时间3.5秒(白屏1.5秒+JS执行2秒),谷歌搜不到内容。
  • Next.js SSG:首屏时间0.5秒(直接返回HTML),谷歌爬虫抓取完整文章,分享卡片完美显示。

用户打开页面立刻看到文章,体验提升了7倍,SEO也来了。

八、总结:别犹豫,新项目就用Next.js

  • 首屏快:SSR/SSG预渲染。
  • SEO好:内容直接写在HTML里。
  • 开发爽:文件路由、API Routes、内置优化。
  • 零配置:比CRA还简单。

如果你还在用CRA写非纯后台的系统,强烈建议试试Next.js。你的用户会感谢你,老板也会夸你。

标签: none

添加新评论