mcpField
S
static-rendering

static-rendering

github.com/patternsdev开发257922 次安装28 周前更新
代码仓库

关于 static-rendering

面向 Web 开发者的静态渲染指南,介绍 Next.js 的数据获取与路由生成,说明预渲染 HTML 适用于不随请求变化的内容。

主要功能

  1. 01构建时生成 HTML
  2. 02构建时获取数据
  3. 03动态路由预渲染
  4. 04CDN 部署指导

适用场景

  1. 01渲染关于和联系页面
  2. 02发布静态博客文章
  3. 03生成商品列表页面

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/patternsdev/skills --skill static-rendering

安装后在 Claude Code 中输入/static-rendering确认已加载。

详细介绍

静态渲染

根据我们对 SSR 的讨论,我们知道,服务器上的请求处理时间过长会对 TTFB 产生负面影响。同样,对于 CSR,JavaScript 包过大会因为脚本的下载和处理耗时而损害应用的 FCP、LCP 和 TTI。

静态渲染或静态生成(SSG)尝试通过向客户端提供预渲染的 HTML 内容来解决这些问题,这些内容是在构建网站时生成的。

适用场景

  • 用于不会因请求而变化的静态内容,例如“关于”页面、博客文章和产品列表
  • 如果你希望通过 CDN 提供的静态 HTML 实现尽可能快的 TTFB,这种方式会很有帮助

不适用场景

  • 对于每次请求都会变化的高度动态、个性化内容(例如用户仪表盘、实时信息流)
  • 数据集过大,导致构建耗时过长,且无法使用 ISR 的情况
  • 页面需要身份验证才能访问内容,且无法在构建时预渲染的情况

说明

  • 使用 getStaticProps(Pages Router)或异步组件(App Router)在构建时获取数据
  • 使用 getStaticPaths / generateStaticParams 预渲染动态路由
  • 对需要定期更新的页面,可以考虑使用增量静态再生成(ISR)
  • 部署到 CDN,以获得边缘缓存性能

详情

系统会预先为用户可以访问的每个路由生成一个静态 HTML 文件。这些静态 HTML 文件可以存放在服务器或 CDN 上,并在客户端请求时获取。

静态文件也可以缓存,从而提高弹性。由于 HTML 响应是预先生成的,服务器上的处理时间几乎可以忽略不计,因此 TTFB 更快,性能也更好。在理想情况下,客户端 JS 应尽可能精简,静态页面应在客户端收到响应后尽快变得可交互。因此,SSG 有助于实现更快的 FCP/TTI。

基本结构

顾名思义,静态渲染适用于静态内容,这类页面无需根据已登录用户进行个性化定制(例如个性化推荐)。因此,网站的“关于我们”“联系我们”页面、博客页面,以及电商应用的产品页面等静态页面,都适合使用静态渲染。Next.js、Gatsby 和 VuePress 等框架都支持静态生成。

Next.js:

// pages/about.js

export default function About() {
  return (
    <div>
      <h1>About Us</h1>
      {/* ... */}
    </div>
  );
}

构建网站时(使用 next build),此页面会预渲染为 HTML 文件 about.html,可通过路由 /about 访问。

使用数据的 SSG

“关于我们”或“联系我们”页面中的静态内容可以直接渲染,无需从数据存储中获取数据。然而,对于单篇博客页面或产品页面等内容,则必须在构建时将数据存储中的数据与特定模板合并,再渲染为 HTML。

列表页面 - 所有项目

在 Next.js 中,可以通过在页面组件中导出函数 getStaticProps() 来实现。构建服务器会在构建时调用此函数来获取数据。

// This function runs at build time on the build server
export async function getStaticProps() {
  return {
    props: {
      products: await getProductsFromDatabase(),
    },
  };
}

// The page component receives products prop from getStaticProps at build time
export default function Products({ products }) {
  return (
    <>
      <h1>Products</h1>
      <ul>
        {products.map((product) => (
          <li key={product.id}>{product.name}</li>
        ))}
      </ul>
    </>
  );
}

该函数不会包含在客户端 JS 包中,因此甚至可以用来直接从数据库获取数据。

单项详情页面 - 每个项目

对于单项详情页面,可以将函数 getStaticPaths() 与动态路由结合使用。

// pages/products/[id].js

export async function getStaticPaths() {
  const products = await getProductsFromDatabase();

  const paths = products.map((product) => ({
    params: { id: product.id },
  }));

  // fallback: false means pages that don't have the correct id will 404.
  return { paths, fallback: false };
}

// params will contain the id for each generated page.
export async function getStaticProps({ params }) {
  return {
    props: {
      product: await getProductFromDatabase(params.id),
    },
  };
}

export default function Product({ product }) {
  // Render product
}
SSG - 关键考量
  1. **大量 HTML 文件:**需要为用户可能访问的每个路由生成单独的 HTML 文件。维护大量 HTML 文件可能颇具挑战。

  2. **托管依赖:**要让 SSG 网站速度极快、响应迅速,用于存储和提供 HTML 文件的托管平台也必须足够出色。如果经过优化的 SSG 网站托管在多个 CDN 上,以利用边缘缓存,则可以实现极佳的性能。

  3. **动态内容:**每次内容发生变化时,都需要构建并重新部署 SSG 网站。如果内容变更后尚未重新构建并部署网站,显示的内容可能会过时。因此,SSG 不适用于高度动态的内容。

来源

评论

支持 Markdown