当构建健壮的 Web 应用程序时,性能优化是一个关键考虑因素。加载缓慢的网站会导致用户沮丧和机会流失。幸运的是,流行的 React 框架 Next.js 提供了一系列强大的功能,以应对性能挑战。在本文中,我们将深入探讨 Next.js 13 的最新模式,帮助您设计高效的组件树,并探索利用客户端和服务器组件的策略。通过阅读本文,您将掌握传递出色的 Web 体验所需的知识和技术。
为了提高应用程序的性能,Next.js 建议尽可能将客户端组件放在组件树的最外层。
例如,假设您有一个包含静态元素(如标志和链接)以及依赖状态的交互式搜索栏的布局组件。与其将整个布局作为客户端组件,最好将交互逻辑提取到其自己的客户端组件中,例如 <SearchBar />
。通过这样做,布局可以保持为服务器组件,避免将不必要的组件 JavaScript 发送到客户端。
下面是一个示意图:
下面是 Next.js 推荐的将客户端组件提取到最外层分支的代码示例。
// SearchBar 是客户端组件
import SearchBar from './searchbar';
// Logo 仍然是服务器组件
import Logo from './logo';
export default function Layout({
children,
}: {
children: React.ReactNode;
}) {
return (
<>
<nav>
<Logo />
<SearchBar />
</nav>
<main>{children}</main>
</>
);
}
通过采用这种方法,您可以确保只有必要的组件在客户端上被渲染,从而提高性能并减少资源开销。
服务器和客户端组件可以在同一组件树中组合使用。
在幕后,React 的渲染处理如下:
阶段1:
当服务器开始工作时,React 会勤勉地渲染所有的服务器组件,确保在发送到客户端之前它们已准备就绪。此渲染阶段甚至包括嵌套在客户端组件中的服务器组件。在此服务器端渲染过程中,React 明智地跳过遇到的任何客户端组件,以便稍后展示它们的光芒。
阶段2:
现在,进入客户端领域。React 再次登场,这次渲染客户端组件并无缝地合并服务器端和客户端的工作。如果客户端组件中包含任何服务器组件,不必担心。React 确保将这些服务器组件的渲染内容精确地放置在客户端组件内的正确位置。
在 Next.js 中将服务器组件集成到客户端组件中时,需要考虑一些限制。不支持直接将服务器组件导入到客户端组件中,因为这将需要额外的服务器往返,影响性能。
不支持的模式:将服务器组件导入到客户端组件中
以下代码模式不受支持:
'use client';
// 这个模式将**不起作用**!
// 不能将服务器组件导入到客户端组件中。
import ExampleServerComponent from './example-server-component';
export default function ExampleClientComponent({
children,
}: {
children: React.ReactNode;
}) {
// ...
return (
<>
<button onClick={() => setCount(count + 1)}>{count}</button>
<ExampleServerComponent />
</>
);
}
推荐的模式:将服务器组件作为属性传递给客户端组件
相反,Next.js 建议使用 React 属性在客户端组件中创建占位符或“洞”,用于放置服务器组件。这样可以确保性能最佳,并将渲染解耦。
推荐的模式:
'use client';
// 这个模式将起作用
import { useState } from 'react';
export default function ExampleClientComponent({
children,
}: {
children: React.ReactNode;
}) {
// ...
return (
<>
<button onClick={() => setCount(count + 1)}>{count}</button>
{children}
</>
);
}
在这种模式中,ExampleClientComponent 不知道其 children 属性的内容,也不知道它最终将由服务器组件的结果填充。它的职责仅仅是确定 children 应该放置在哪里。
父服务器组件的使用:
// 这个模式有效:
// 您可以将服务器组件作为客户端组件的子项或属性传递。
import ExampleClientComponent from './example-client-component';
import ExampleServerComponent from './example-server-component';
export default function Page() {
return (
<ExampleClientComponent>
<ExampleServerComponent />
</ExampleClientComponent>
);
}
通过遵循这个推荐的模式,Next.js 提供了一种有效地组合组件的方法,提高了性能,并保持了服务器端和客户端渲染之间的关注点分离。
总之,在 Next.js 中,提供了强大的功能和模式来优化 Web 应用程序的性能。通过将客户端组件放置在组件树的最外层,可以避免不必要的 JavaScript,从而提高性能并减少资源开销。此外,Next.js 允许无缝组合客户端和服务器组件,利用服务器端渲染来确保在客户端上高效地渲染和合并组件。当在客户端组件中集成服务器组件时,重要的是要遵循使用 React 属性将服务器组件传递为占位符的推荐模式,以实现最佳性能并解耦渲染。通过实施这些技术并利用 Next.js 的优势,开发人员可以提供快速的 Web 体验,并提高应用程序的整体性能。