static-rendering
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseStatic Rendering
静态渲染
Based on our discussion on SSR, we know that a high request processing time on the server negatively affects the TTFB. Similarly, with CSR, a large JavaScript bundle can be detrimental to the FCP, LCP and TTI of the application due to the time taken to download and process the script.
Static rendering or static generation (SSG) attempts to resolve these issues by delivering pre-rendered HTML content to the client that was generated when the site was built.
基于我们对SSR的讨论,我们知道服务器上较长的请求处理时间会对TTFB产生负面影响。同样,对于CSR来说,由于下载和处理脚本需要时间,较大的JavaScript包会损害应用的FCP、LCP和TTI。
静态渲染(又称静态生成,SSG)试图通过向客户端提供在站点构建时生成的预渲染HTML内容来解决这些问题。
When to Use
适用场景
- Use this for static content like About pages, blog posts, and product listings that don't change per-request
- This is helpful when you want the fastest possible TTFB via CDN-served static HTML
- 适用于“关于我们”页面、博客文章、产品列表等不会随请求变化的静态内容
- 当你希望通过CDN提供的静态HTML实现最快的TTFB时,这种方式非常有用
Instructions
操作指南
- Use (Pages Router) or async components (App Router) to fetch data at build time
getStaticProps - Use /
getStaticPathsto pre-render dynamic routesgenerateStaticParams - Consider Incremental Static Regeneration (ISR) for pages that need periodic updates
- Deploy to a CDN for edge-cached performance
- 使用(Pages Router)或异步组件(App Router)在构建时获取数据
getStaticProps - 使用/
getStaticPaths预渲染动态路由generateStaticParams - 对于需要定期更新的页面,可以考虑使用增量静态再生(ISR)
- 部署到CDN以实现边缘缓存性能
Details
详细说明
A static HTML file is generated ahead of time corresponding to each route that the user can access. These static HTML files may be available on a server or a CDN and fetched as and when requested by the client.
Static files may also be cached thereby providing greater resiliency. Since the HTML response is generated in advance, the processing time on the server is negligible thereby resulting in a faster TTFB and better performance. In an ideal scenario, client-side JS should be minimal and static pages should become interactive soon after the response is received by the client. As a result, SSG helps to achieve a faster FCP/TTI.
会提前为用户可访问的每个路由生成对应的静态HTML文件。这些静态HTML文件可能存储在服务器或CDN上,在客户端请求时被获取。
静态文件还可以被缓存,从而提供更强的弹性。由于HTML响应是提前生成的,服务器上的处理时间可以忽略不计,因此能实现更快的TTFB和更好的性能。在理想情况下,客户端JS应尽可能精简,静态页面在客户端收到响应后应很快变得可交互。因此,SSG有助于实现更快的FCP/TTI。
Basic Structure
基本结构
As the name suggests, static rendering is ideal for static content, where the page need not be customized based on the logged-in user (e.g personalized recommendations). Thus static pages like the 'About us', 'Contact us', Blog pages for websites or product pages for e-commerce apps, are ideal candidates for static rendering. Frameworks like Next.js, Gatsby, and VuePress support static generation.
Next.js:
js
// pages/about.js
export default function About() {
return (
<div>
<h1>About Us</h1>
{/* ... */}
</div>
);
}When the site is built (using ), this page will be pre-rendered into an HTML file accessible at the route .
next buildabout.html/about顾名思义,静态渲染非常适合静态内容,即页面无需根据登录用户进行定制(例如个性化推荐)。因此,网站的“关于我们”、“联系我们”、博客页面,或电商应用的产品页面,都是静态渲染的理想候选。Next.js、Gatsby和VuePress等框架都支持静态生成。
Next.js示例:
js
// pages/about.js
export default function About() {
return (
<div>
<h1>About Us</h1>
{/* ... */}
</div>
);
}当站点构建完成(使用命令)后,该页面会被预渲染为HTML文件,可通过路由访问。
next buildabout.html/aboutSSG with Data
带数据的SSG
Static content like that in 'About us' or 'Contact us' pages may be rendered as-is without getting data from a data-store. However, for content like individual blog pages or product pages, the data from a data-store has to be merged with a specific template and then rendered to HTML at build time.
“关于我们”或“联系我们”页面中的静态内容可以直接渲染,无需从数据存储中获取数据。然而,对于单个博客页面或产品页面这类内容,需要将数据存储中的数据与特定模板合并,然后在构建时渲染为HTML。
Listing Page - All Items
列表页面 - 所有项目
In Next.js this can be achieved by exporting the function in the page component. The function is called at build time on the build server to fetch the data.
getStaticProps()js
// 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>
</>
);
}The function will not be included in the client-side JS bundle and hence can even be used to fetch the data directly from a database.
在Next.js中,可以通过在页面组件中导出函数来实现。该函数会在构建时在构建服务器上被调用以获取数据。
getStaticProps()js
// 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包中,因此甚至可以直接从数据库获取数据。
Individual Details Page - Per Item
详情页面 - 单个项目
For individual details pages, we can use the function in combination with dynamic routes.
getStaticPaths()js
// 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
}对于单个详情页面,我们可以结合动态路由使用函数。
getStaticPaths()js
// 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 - Key Considerations
SSG - 关键注意事项
Note (React 18+ / Next.js 13+): Modern Static GenerationIn Next.js 13's App Router,andgetStaticPropshave their equivalents ingetStaticPaths(for dynamic routes) and the ability to fetch data in an async component for static generation.generateStaticParamsUse Incremental Static Regeneration (ISR) for Freshness: If you have pages that are mostly static but need periodic updates, set ainterval or use on-demand revalidation.revalidatePartial Prerendering (PPR): A recent development in Next.js 14+ is Partial Prerendering, which allows a page to be partially statically rendered at build time and partially filled in at request time.
-
A large number of HTML files: Individual HTML files need to be generated for every possible route that the user may access. Maintaining a large number of HTML files can be challenging.
-
Hosting Dependency: For an SSG site to be super-fast and respond quickly, the hosting platform used to store and serve the HTML files should also be good. Superlative performance is possible if a well-tuned SSG website is hosted right on multiple CDNs to take advantage of edge-caching.
-
Dynamic Content: An SSG site needs to be built and re-deployed every time the content changes. The content displayed may be stale if the site has not been built + deployed after any content change. This makes SSG unsuitable for highly dynamic content.
注意(React 18+ / Next.js 13+):现代静态生成在Next.js 13的App Router中,和getStaticProps的替代方案是**getStaticPaths**(用于动态路由),以及在异步组件中获取数据以实现静态生成的能力。generateStaticParams**使用增量静态再生(ISR)保持内容新鲜度:**如果你的页面大部分是静态的但需要定期更新,可以设置间隔或使用按需重新验证。revalidate**部分预渲染(PPR):**Next.js 14+中的一项最新功能是部分预渲染,它允许页面在构建时部分静态渲染,在请求时填充剩余部分。
-
**大量HTML文件:**需要为用户可能访问的每个路由生成单独的HTML文件。维护大量HTML文件可能具有挑战性。
-
**托管依赖:**为了让SSG站点超级快速并快速响应,用于存储和提供HTML文件的托管平台也需要具备良好性能。如果经过优化的SSG网站部署在多个CDN上,利用边缘缓存,就能实现极佳的性能。
-
**动态内容:**每次内容更改时,都需要重新构建和部署SSG站点。如果内容更改后未进行构建+部署,显示的内容可能会过时。这使得SSG不适合高度动态的内容。