默认情况下,Next.js 预渲染每个页面。这意味着 Next.js 为每个页面生成 HTML,而不是让它全部由客户端 JavaScript 完成。预渲染可以使项目拥有更好的性能和搜索引擎优化。
每个生成 HTML 与该页所需的最小 JavaScript 代码相关联。当一个页面被浏览器加载时,它的 JavaScript 代码就会运行并使页面完全交互。(此过程称为hydration.)
检查是否正在进行预渲染
你可以通过以下步骤检查预呈现是否正在进行:
- 禁用浏览器中的 JavaScript (这里是如何在 Chrome 浏览器中操作 https://developers.google.com/web/tools/chrome-devtools/javascript/disable)
- 尝试访问此页面 (本教程的最终结果https://next-learn-starter.now.sh/)。
你应该看到应用程序是在没有 JavaScript 的情况下呈现的。这是因为 Next.js 将应用程序预呈现为静态 HTML,允许你在不运行 JavaScript 的情况下查看应用程序 UI。
注意: 你也可以在
localhost
上尝试上述步骤,但是如果禁用 JavaScript,CSS 将不会加载。
如果你的应用程序是一个普通的 React.js 应用程序(没有 Next.js),就没有预呈现功能,所以如果禁用 JavaScript,你将无法看到该应用程序。例如:
- 在浏览器中启用 JavaScript 并查看此页面。这是一个普通的 React.js 应用程序,由Create React App 构建。
- 现在,禁用 JavaScript 并再次访问相同的页面。
- 你不会再看到这个应用了 — 相反,它会说:“You need to enable JavaScript to run this app.”。这是因为应用程序没有预渲染为静态 HTML。
总结: 预渲染与无预渲染
这里是一个快速的图形化总结:
Next.js 有两种预呈现形式: 静态生成 and 服务器端渲染。不同之处在于它 什么时机 生成了每一页的 HTML。
- 静态生成 是在编译环节预生成 HTML 然后在每个请求上_重复使用_的预渲染方法。
- 服务器端渲染 在每个请求时生成 HTML 的预渲染方法。
在开发模式下(当你运行
npm run dev
或yarn dev
),每个请求都预渲染每一页——甚至对于使用静态生成的页面也是如此。
每页标准
重要的是,Next.js 允许你选择每一页使用的预渲染形式。你可以为大多数页面使用静态生成并为其他页面使用服务器端呈现来创建一个“混合的” Next.js 应用程序。
何时使用静态生成 v.s. 服务器端渲染
我们建议使用静态生成(带数据和不带数据),因为你的页面可以构建一次,由 CDN 提供服务,这使得它比让服务器在每个请求上呈现页面要快得多。
你可以对许多类型的页面使用静态生成,包括:
- 地推页面
- 博客文章
- 电子商贸产品目录
- 协助和文件
你应该问问自己:“我能在用户请求这个页面之前预渲染吗?”如果答案是肯定的,那么你应该选择静态生成。
另一方面,如果你无法在用户请求之前预渲染页面,那么静态生成就不是一个好主意。也许你的页面显示频繁更新的数据,页面内容在每个请求上都会改变。
在这种情况下,你可以使用服务器端渲染.它将会更慢,但预渲染的页面将永远是最新的。或者,你可以跳过预渲染,并使用客户端 JavaScript 来填充数据。
我们将专注于静态生成
在本课中,我们将重点讨论静态生成。在下一页中,我们将讨论在有或没有数据的情况下静态生成页面。
有或无数据的静态生成
静态生成可以使用和不使用数据来完成。
到目前为止,我们创建的所有页面都不需要获取外部数据。这些页面将在应用程序编译的时候自动静态生成。
然而,对于某些页面,你可能无法在不先获取一些外部数据时呈现 HTML。你可能需要访问文件系统、获取外部 API 或在构建时查询数据库。Next.js 支持这种情况 — 有数据的静态生成 — 开箱即用。
使用 getStaticProps
的有数据的静态生成
它是如何工作的?在 Next.js 中,当导出一个页面组件时,还可以导出一个名为getStaticProps
的 async
函数。如果你这样做,那么:
- 在生产过程中,在构建时运行
getStaticProps
。 - 在函数内部,你可以获取外部数据并将其作为页面的属性传递。
export default function Home(props) { ... } export async function getStaticProps() { // Get external data from the file system, API, DB, etc. const data = ... // The value of the `props` key will be // passed to the `Home` component return { props: ... } }
本质上,getStaticProps
允许你告诉 Next.js:“嘿,这个页面有一些数据依赖关系 — 所以当你在构建时预渲染这个页面时,一定要先处理它们!”
注意: 在开发模式下,
getStaticProps
在每个请求时运行。