静态和动态渲染
在上一章中,您为 Dashboard 概述页面获取了数据。但是,我们简要讨论了当前设置的两个局限性:
以下是本章中将涵盖的主题:
什么是静态渲染?
使用静态渲染,数据获取和渲染在构建时(部署时)或 重新验证期间 (opens in a new tab) 在服务器上进行。然后,结果可以在 内容分发网络(CDN) (opens in a new tab) 中分发和缓存。
每当用户访问你的应用程序时,缓存的结果都会被提供。静态渲染有几个好处:
静态渲染对于 没有数据 或 跨用户共享数据 的 UI(如静态博客文章或产品页面)非常有用。它可能不适合具有定期更新的个性化数据的 Dashboard。
与静态渲染相反的是动态渲染。
是时候做个测验了!
什么是动态渲染?
通过动态渲染,内容在请求时(当用户访问页面时)在服务器上为每个用户呈现。动态渲染有几个好处:
是时候做个测验了!
使 Dashboard 动态化
默认情况下,
@vercel/postgresql
不设置自己的缓存语义。这允许框架设置自己的静态和动态行为。
您可以在服务器组件或数据获取函数中使用名为
unstable_noStore
的 Next.js API 来选择退出静态呈现。让我们添加这个。
在你的
data.ts
中,从
next/cache
导入
unstable_noStore
,并在数据获取函数的顶部调用它:
// ... import { unstable_noStore as noStore } from 'next/cache'; export async function fetchRevenue() { // Add noStore() here to prevent the response from being cached. // This is equivalent to in fetch(..., {cache: 'no-store'}). noStore(); // ... export async function fetchLatestInvoices() { noStore(); // ... export async function fetchCardData() { noStore(); // ... export async function fetchFilteredInvoices( query: string, currentPage: number, noStore(); // ... export async function fetchInvoicesPages(query: string) { noStore(); // ... export async function fetchFilteredCustomers(query: string) { noStore(); // ... export async function fetchInvoiceById(query: string) { noStore(); // ...
注意:
unstable_noStore
是一个实验性的 API,可能在将来发生变化。如果您更喜欢在自己的项目中使用稳定的 API,您也可以使用 Segment 配置选项 (opens in a new tab)export const dynamic = "force-dynamic"
。模拟慢速数据获取
使 Dashboard 动态化是迈出的良好第一步。然而... 还有一个我们在上一章提到的问题。如果一个数据请求比其他所有请求都慢,会发生什么?
让我们模拟一次慢速数据获取。在您的
data.ts
文件中,取消注释fetchRevenue()
函数内部的console.log
和setTimeout
:/app/lib/data.tsexport async function fetchRevenue() { try { // 为演示目的,我们人为延迟响应。 // 在生产中请勿这样做 :) console.log('Fetching revenue data...'); await new Promise((resolve) => setTimeout(resolve, 3000)); const data = await sql<Revenue>`SELECT * FROM revenue`; console.log('Data fetch completed after 3 seconds.'); return data.rows; } catch (error) { console.error('Database Error:', error); throw new Error('Failed to fetch revenue data.');
现在在新标签页中打开 http://localhost:3000/dashboard/, (opens in a new tab) 注意页面加载所需的时间较长。在终端中,您还应该看到以下消息: