Back

Next.js 系列 06:服务器组件的好处

Published on 10th September 2024

Next.js 系列 04:服务器组件之前 篇章里,我说过,能改善 DX(Developer Experience)的技术就是好技术。RSC 对我来说, 最明显的好处就是 DX 的提升,因为它获取数据变得更加灵活。

但不是所有人都抱有此观念。我曾看到有人抱怨:

使用 App Router,我项目里几乎所有文件都得加 ‘use client’,超级麻烦。

这种抱怨存在误解,因为客户端组件具有“传染性”(我会在后续章节展开说明),不是都得加 use client 才是客户端组件。如果你的项目迁移起来很麻烦,并且没有充裕的时间,那么没有必要做迁移, 但建议新项目优先考虑 RSC,因为它确实有更好的性能,只不过开发人员要不断思考“服务器上正在运行什么?客户端上正在运行什么?”。

几乎所有介绍 RSC 的资料,都会提及减小客户端大小,提高性能,我也准备了一个例子。

在 Next 中引入 highlight.js 来实现代码高亮。

import hljs from "highlight.js/lib/core";
import javascript from "highlight.js/lib/languages/javascript";
import "highlight.js/styles/github-dark.css";

hljs.registerLanguage("javascript", javascript);

const code = "console.log('Hello world')";
const highlightedCode = hljs.highlight(code, {
  language: "javascript",
}).value;

export default function Home() {
  return (
    <pre>
      <code dangerouslySetInnerHTML={{ __html: highlightedCode }}></code>
    </pre>
  );
}

客户端组件需要在文件头添加 ‘use client’

我们使用 @next/bundle-analyzer 来观察打包后客户端的代码。

服务器组件
客户端组件

可以看到,使用服务器组件,highlight.js 的 js 代码没有被打包到客户端,意味着帮你节省超过 80KB 大小的客户端文件,并减少 Hydration 过程的工作量。

前面说过,RSC 只在服务器运行,并且有着更灵活的数据获取方式,如果你正在用 Next.js 构建一份全栈应用,可以畅快编写如下代码:

import db from './database';

async function User({ id }) {
  const user = await db.users.get(id);

  return (
    <div>
      <img src={user.avatar} alt="avatar" />
      <p>{user.name}</p>
    </div>
  );
}

它就像以前我们写 PHP 的时候一样便利。

下一篇,我们来看『客户端组件的传染性』以及『即使状态发生改变,也不会重新渲染』。