基于Nextjs15的学习手记
基于Nextjs15的学习手记
Next.js 是一个基于 React 的 全栈框架,由 Vercel 维护。它提供了 服务器端渲染(SSR) 、静态站点生成(SSG) 、增量静态再生(ISR) 等特性,使得开发者可以更轻松地构建高性能、SEO 友好的 Web 应用。目前Nextjs 15已经使用React 19版本,服务器组件更加强悍。
一、了解CSR/SSR/SSG
CSR(Client-Side Rendering,客户端渲染)、SSR(Server-Side Rendering,服务器端渲染)和SSG(Static Site Generation,静态站点生成)是构建现代Web应用的不同的渲染方式。主要区别在于 页面的 HTML 何时生成、在哪里生成,以及对 SEO 和性能的影响,每种方式都有其优缺点,适用于不同的场景。
1.CSR(客户端渲染)
将网页的内容生成和渲染都放在客户端(即浏览器)完成。初始的HTML文档中通常只包含基本的骨架和一些静态资源链接,如CSS和JavaScript文件。然后,浏览器会下载这些文件,并在客户端解析和执行JavaScript代码,动态地获取数据,并使用数据来生成和渲染页面的内容。
适用于单页应用(SPA) ,比如 React、Vue 项目
CSR渲染过程:
①.下载初始HTML
②.解析HTML
③.下载和执行JavaScript文件
④.数据获取
⑤.数据处理和页面渲染
⑥.更新DOM
⑦.用户交互和动态更新
优点:
-
富交互性:客户端渲染允许创建富交互性的应用,因为所有的逻辑都在用户的浏览器中执行。
-
减轻服务器负载:服务器只需提供静态文件,大部分工作由客户端完成,减轻了服务器的负载。
-
更快的页面导航:在单页面应用(SPA)中,页面之间的导航可以无需重新加载整个页面,提供了更流畅的用户体验。
缺点:
-
SEO挑战:由于内容是在客户端动态生成的,搜索引擎可能难以抓取页面内容,这可能对SEO造成不利影响。
-
慢首屏加载:客户端渲染通常需要加载JavaScript框架和应用代码,然后才能渲染内容,这可能导致慢首屏加载时间。
-
JavaScript依赖:完全依赖于客户端JavaScript执行,如果用户禁用了JavaScript,或者JavaScript文件加载失败,那么用户将看不到任何内容。
适用场景:
- 后台管理系统(如 CMS、Admin 面板)。
- 需要大量交互的 SPA(如 Gmail、React/Vue App)。
- 对 SEO 要求不高的应用。
2.SSR(服务器端渲染)
在SSR中,服务器会在接收到客户端请求后,执行网页的渲染逻辑,并生成完整的HTML页面。生成的HTML页面包含了所有初始化的数据和已经渲染好的页面内容,然后服务器将该HTML页面发送给客户端浏览器进行展示。
SSR渲染过程:
①.客户端请求
②.路由处理
③.数据获取
④.数据处理和页面渲染
⑤.HTML页面发送
⑥.客户端渲染
⑦.数据绑定和事件处理
⑧.用户交互和动态更新
优点:
-
SEO优化:服务器端渲染的页面可以提供完整的HTML内容,有助于搜索引擎更好地抓取和索引网站,从而提高SEO表现。
-
快速首屏加载:用户可以更快地看到完整渲染的页面,因为内容是在服务器上生成的,这提高了 perceived performance(用户感知的性能)。
-
更好的社交媒体共享:由于页面的元数据(如标题、描述、图片等)在服务器上已经渲染,分享链接时社交媒体平台能够正确显示预览信息。
缺点:
-
服务器负载:服务器端渲染可能会增加服务器的负载,因为每个页面请求都需要服务器处理和渲染。
-
延迟:页面更新或导航可能会有延迟,因为需要从服务器获取新的HTML页面。
-
复杂的构建和部署:SSR应用可能需要特殊的服务器配置和更复杂的构建过程。
适用场景:
-
SEO 要求高的应用(如官网、博客、新闻站点)。
-
内容动态变化的页面(如用户个性化主页)。
3.SSG (静态网站生成)
在构建(build)阶段生成静态HTML文件,将这些文件直接提供给客户端,而无需在每个请求上动态生成内容。
SSG渲染过程:
①.构建阶段
②.生成静态文件
③.服务器提供静态文件
④.客户端渲染
优点:
-
最快的加载速度:用户访问时,直接从 CDN 获取 HTML,加载速度快。
-
SEO 友好:完整 HTML 可被爬虫抓取。
-
服务器压力低:只需要提供静态文件。
缺点:
-
缺少灵活性:无法处理实时数据,页面内容不会随请求变化。
-
更新繁琐:如果数据更新,需要重新构建页面。
适用场景:
- 博客、文档、产品展示页(如 Next.js + Markdown 博客)。
- 新闻站点(非实时) 。
- 静态电商页面(如 Next.js + Shopify)。
4.CSR / SSR / SSG 对比
| 渲染方式 | HTML 生成时机 | 是否支持 SEO | 首屏速度 | 适用场景 |
|---|---|---|---|---|
| CSR | 浏览器端 | ❌ 差 | 🐢 慢 | SPA、后台管理系统 |
| SSR | 请求时 | ✅ 好 | 🚀 快 | SEO 需求高、动态数据 |
| SSG | 构建时 | ✅ 最优 | ⚡ 超快 | 博客、文档、静态页面 |
CSR提供富交互和动态内容,能够实现流畅的用户体验,适用于单页应用和需要复杂前端逻辑的应用。
SSR提供更快的首次加载速度、SEO友好和较好的性能,适用于需要复杂交互和对SEO重视的应用。
SSG提供更快的加载速度、SEO友好和较好的可访问性,适用于内容相对稳定、对SEO要求较高或需要更快加载速度的应用。
5.同构(Isomorphic)渲染
也叫 混合渲染(Hybrid Rendering),结合了SSR和CSR的优点,首次请求由服务器渲染页面,提供快速的首屏加载和良好的SEO,之后的页面交互由客户端接管,提供富交互性。这种方式需要更复杂的配置和架构设计,但可以提供更好的用户体验和性能。
6.ISR(增量静态再生)
ISR(Incremental Static Regeneration),SSG 的增强版,允许部分页面在后台自动更新,无需手动重新构建。
7.汇总
Next.js 是一个 React 框架,可用于构建 SSR、CSR 和 SSG 网站和应用程序,且支持同构渲染和增量静态再生。 以及提供了许多内置功能,例如路由、数据获取和预渲染,Nextjs不仅当前强大,还在不断进化适合企业长期使用。
二、React 19新特性
三、基于React 19的Nextjs 15
- dev:运行next dev启动 Next.js开发模式。
- build:运行next build构建生产应用包。
- start:运行next start启动 Next.js 生产应用包。
- lint:运行next lint设置 Next.js 的内置 ESLint 配置。
1.核心规则
| 组件类型 | 是否需要标记 | 说明 |
|---|---|---|
| 服务端组件 | 不需要标记(默认启用) |
.jsx/.tsx 文件默认就是服务端组件 |
| 客户端组件 | 必须加 'use client'
|
任何需要 useState/Effect/浏览器 API 的组件 |
| 服务端动作 | 必须加 'use server'
|
处理表单提交等服务器端操作的函数 |
CSR客户端组件
文件起头添加use client标识,可以使用浏览器APi(如:localStorage等),添加交互性事件和事件侦听器。
// pages/test01
"use client"
import {useEffect, useState} from "react";
export default function Test01 () {
const [name, setName] = useState('');
useEffect(() => {
fetch(...).then(res => setName(res));
}, [])
return <div>
<div>name: {name}</div>
</div>
}
![]()
浏览器第一时间得到的结果没有userName实际值,不利于SEO,结果需要等待请求到真实数据后,通过js操作dom进行回显
SSR服务端组件
.jsx/.tsx 文件默认就是服务端组件,可以使用内置方法getServerSideProps获取服务端数据,并以props形式回传给当前组件
// pages/test02
export default function Test02 ({ name }: { name: string }) {
return <div>
<div>name: {name}</div>
</div>
}
export async function getServerSideProps() {
const name = await fetch(...)
return { props: { name } }
}
![]()
在服务器中请求数据后,直接将数据拼接到html中,并将组合好数据的html结构传给浏览器,有利于SEO
RSC服务器组件
React Server Components也是服务端渲染,是基于SSR之上的方案,在/app目录下创建的页面,默认就是RSC服务器组件
// app/page.jsx (默认RSC)
export default function Page() {
// 直接使用 async/await 获取数据、访问数据库
const data = await fetch(...)
return <div>{data}</div>
}
通过流式处理(Suspense + lazy),您可以从服务器逐步呈现 UI。工作被拆分为块,并在客户端准备就绪时流式传输到客户端。这允许用户在整个内容完成渲染之前立即看到页面的某些部分。
![]()
通过浏览器插件React Developer Tools,查看当前app/page.jsx页面组件层级,即可看到其底层组件层级。
![]()
2.服务端组件和客户端组件使用核规则
尽量整个页面为服务器组件(RSC),即可灵活引入各类型组件。
客户端组件
- 客户端组件子组件必须是客户端组件
// src/components/Header
export default async function Header() {
const data = await fetch(...);
return (
<div>
header
</div>
);
}
// src/pages/page1
"use client"
import Header from "@/components/Header";
export default function Page1() {
return (
<div>
<div>Page1</div>
<Header />
</div>
);
}
Header为服务端组件,作为子组件被客户端组件引用时,页面报错。
![]()
-
服务器组件可以作为客户端组件的插槽
-
服务器组件可以作为客户端组件的属性
-
Context组件通信必须在客户端组件中来完成
服务器组件
- 服务器组件和客户端组件都能作为服务器组件子组件
外部依赖组件
- 如果当前页面需要引入外部依赖中的组件报错,可能是外部依赖组件没有使用
use client标识,导致将其作为服务端组件进行使用从而你报错,可创建客户端组件包裹依赖组件即可。