服务器端渲染指南

服务器端渲染 (SSR) 已经存在了一段时间,但值得进一步探索。这种技术可以使您的网络应用程序更快、更适合 SEO。
在本指南中,我们将解释 SSR、为什么您可能想要使用它,以及如何在不费吹灰之力的情况下实现它。我们将介绍基础知识,将其与客户端渲染进行比较,并讨论一些实际示例。

什么是服务器端渲染?

从根本上来说,SSR 是在服务器上而不是在浏览器中渲染网页。当用户请求页面时,服务器会完成所有繁重的工作并将完全呈现的页面发送到客户端。然后,客户端 JavaScript 接管使其具有交互性。

服务器在厨房里做准备工作,浏览器只需要装盘和上菜。

这是一个最小的 Express.js 示例:

const express = require('express')
const React = require('react')
const ReactDOMServer = require('react-dom/server')
const App = require('./App')

const app = express()

app.get('/', (req, res) => {
const html = ReactDOMServer.renderToString(<App />)
res.send(`
<!DOCTYPE html>
<html>
<body>
<div id="root">${html}</div>
<script src="client.js"></script>
</body>
</html>
`)
})

app.listen(3000, () => console.log('Server running on port 3000'))

从服务器到具有完全渲染页面的浏览器

当我们谈论 SSR 提供 ​​“完全渲染的页面”时,了解其实际含义非常重要。让我们来分解一下:

什么是完全渲染的页面?

完全呈现的页面是一个 HTML 文档,其中包含用户首次加载页面时将获得的所有内容。这包括:

  1. 完整的 DOM 结构
  2. 所有文字内容
  3. 图像占位符和其他媒体元素
  4. 初始样式

这是一个基本示例:

<!DOCTYPE html>
<html>
<head>
<title>My SSR Page</title>
<style>
/* Initial styles */
</style>
</head>
<body>
<header>
<h1>Welcome to My Site</h1>
<nav><!-- Fully populated navigation --></nav>
</header>
<main>
<article>
<h2>Article Title</h2>
<p>This is the full content of the article...</p>
</article>
</main>
<footer><!-- Fully populated footer --></footer>
<script src="hydration.js"></script>
</body>
</html>

和 CSR 的区别

相比之下,客户端呈现 (CSR) 的初始 HTML 可能如下所示:

<!DOCTYPE html>
<html>
<head>
<title>My CSR Page</title>
</head>
<body>
<div id="root"></div>
<script src="bundle.js"></script>
</body>
</html>

CSR 页面完全依赖 JavaScript 来填充内容。

完全呈现 HTML 的好处

  1. 更快的初始绘制:浏览器可以立即开始渲染内容。
  2. 更好的 SEO :搜索引擎无需执行 JavaScript 即可读取您的所有内容。
  3. 改进的可访问性:屏幕阅读器和其他辅助技术可以立即访问内容。
  4. 弹性:即使 JavaScript 无法加载,基本内容也可用。

水合过程

发送完全渲染的 HTML 后,SSR 应用程序通常会经历一个称为 Hydration(水合) 的过程:

  1. 服务器发送完全呈现的 HTML。
  2. 浏览器立即显示此 HTML。
  3. JavaScript 加载并水合页面,增加交互性。
// Simplified React hydration example
import { hydrateRoot } from 'react-dom/client'
import App from './App'

const domNode = document.getElementById('root')
hydrateRoot(domNode, <App />)

此过程允许快速初始加载,同时仍然提供现代 Web 应用程序的丰富交互性。

请记住,虽然 SSR 提供了这些完全渲染的页面,但它并非没有权衡。服务器执行更多工作,您需要仔细处理服务器和客户端之间的状态。然而,对于许多应用程序来说,完全渲染页面的好处使 SSR 成为一个令人信服的选择。

CSR 和 SSR 有什么区别?

客户端渲染 (CSR) 和服务器端渲染 (SSR) 是渲染网页的两种不同方法。以下是它们主要差异的细分:

客户端渲染 (CSR)

  1. 服务器发送带有 JavaScript 包的最小 HTML 文件。
  2. 浏览器下载并运行 JavaScript。
  3. JavaScript 创建页面内容并使其具有交互性。

优点:

  • 初始加载后交互顺畅
  • 需要更少的服务器资源

缺点:

  • 初始页面加载速度较慢
  • 潜在的 SEO 挑战

服务器端渲染(SSR)

  1. 服务器创建完整的 HTML 内容。
  2. 浏览器快速接收并显示预渲染的 HTML。
  3. 然后加载 JavaScript 以使页面完全交互。

优点:

  • 更快的初始页面加载
  • 更适合搜索引擎优化
  • 在较慢的设备上运行良好

缺点:

  • 设置起来可能会更复杂
  • 可能会使用更多服务器资源

这是一个简单的视觉比较:

本质上,CSR 更多地在浏览器中工作,而 SSR 更多地在服务器上工作。它们之间的选择取决于项目的具体需求,平衡初始加载时间、SEO 要求和服务器资源等因素。

SSR 和搜索引擎:HTTP 中的匹配

服务器端渲染会对搜索引擎如何看待您的网站产生重大影响。让我们来分解一下:

  1. 更快的索引

    搜索引擎机器人不耐烦。他们现在就想看到您的内容。借助 SSR,当机器人来敲门时,您的页面就已准备就绪,无需等待 JavaScript 加载和渲染。

  2. 内容一致性

    SSR 确保搜索引擎看到的内容与用户看到的内容相同。使用客户端渲染时,始终存在机器人可能会错过某些动态加载内容的风险。

  3. 缩短加载时间

    搜索引擎喜欢快速的网站。 SSR 可以显着缩短初始加载时间,这可以让您在排名中稍占优势。

    // Pseudo-code for search engine ranking
    function calculateRanking(site) {
    let score = site.relevance
    if (site.loadTime < FAST_THRESHOLD) {
    score += SPEED_BONUS
    }
    return score
    }
  4. 移动优先索引

    借助 Google 的移动优先索引,SSR 在较慢的移动连接上的性能优势变得更加重要。

  5. 社交媒体预览

    虽然严格来说 SSR 并不是一项搜索引擎功能,但当您的内容在社交平台上共享时,SSR 可以更轻松地生成准确的预览。这可以通过增加参与度和反向链接来间接提高您的搜索引擎优化。

    <!-- SSR makes it easier to include accurate meta tags -->
    <meta property="og:title" content="Your Dynamic Title Here" />
    <meta property="og:description" content="Your Dynamic Description Here" />

SSR 是 SEO 的强大工具,但它不是唯一的因素。内容质量、相关性和整体用户体验对于搜索引擎排名至关重要。 SSR 只是确保搜索引擎可以有效地抓取和索引您的内容,从而有可能为您提供可见性和性能指标方面的优势。

如何实际进行 SSR

实施 SSR 并不一定很复杂。让我们介绍一下如何使用 Next.js 来实现这一点,Next.js 是一个流行的 React 框架,可以让 SSR 变得简单:

  1. 设置 Next.js 项目。
  2. 创建服务器端呈现的页面。
  3. 让 Next.js 处理完全渲染的 HTML 和客户端水合作用。

这是一个使用 App Router 的简单 Next.js 示例:

// app/page.js
async function getData() {
const res = await fetch('<https://api.example.com/data>')
if (!res.ok) {
throw new Error('Failed to fetch data')
}
return res.json()
}

export default async function Home() {
const data = await getData()

return <h1>Hello {data.name}</h1>
}

在这个例子中:

  • Home组件是一个异步函数,允许服务器端数据获取。
  • getData()获取我们需要的数据。
  • 该组件直接呈现数据。

Next.js 自动处理 SSR 流程:

  1. 当请求到来时,Next.js 在服务器上运行该组件。
  2. 它等待获取数据。
  3. 它使用获取的数据呈现组件。
  4. 完全呈现的 HTML 将发送到客户端。
  5. 一旦 JavaScript 在浏览器中加载,页面就会变成交互式的。

这种方法为您提供了 SSR 的优势,而无需手动设置服务器或自行管理渲染过程。

更高级别的 SSR 解决方案

如果您不想重新发明轮子,有几个框架可以为您处理 SSR 复杂性。以下是不同生态系统中流行选项的概述:

React

  • Next.js :最流行的 React 框架,具有内置的 SSR 支持。
  • Remix :一个利用 React Router 的全栈 Web 框架。
  • Gatsby :主要是静态站点生成器,但也支持 SSR。

Vue

  • Nuxt.js :具有 SSR 功能的 Vue 应用程序的首选框架。

Angular

  • Angular Universal:Angular 应用程序的官方 SSR 解决方案。

Svelte

  • SvelteKit :Svelte 的官方应用程序框架,支持 SSR。

JavaScript(Framework-agnostic)

  • Astro :允许您使用多个框架并支持 SSR。
  • Qwik :一个新框架,旨在通过内置 SSR 支持实现最佳性能。

PHP

  • Laravel :通过 Inertia.js 或其自己的 Livewire 组件提供 SSR 功能。

Ruby

  • Ruby on Rails :通过 Stimulus ReflexHotwire 等工具支持 SSR。

Python

  • Django :可以使用 Django-Unicorn 或 HTMX 等库实现 SSR。
  • Flask :可以配置为 SSR,通常与 Flask-SSE 等扩展一起使用。

这些框架中的每一个都提供了自己的 SSR 方法,通常还具有静态站点生成、API 路由等附加功能。选择取决于您的首选语言、生态系统和特定项目要求。

部署和缓存

部署 SSR 应用程序时:

  1. 构建客户端和服务器端包。
  2. 将 SSR 服务器作为后台进程运行。
  3. 使用 PM2Supervisor 等进程监视器来保持服务器运行。

这是基本的部署流程:

不要忘记缓存!缓存服务器渲染的页面可以显着减少服务器负载。

使用 Builder.io 进行 SSR

Builder.io 为所有组件和框架的服务器端渲染 (SSR) 和静态站点生成 (SSG) 提供支持。这种开箱即用的功能使您无需额外设置即可利用 SSR 和 SSG 的优势。

主要特点

  1. 与框架无关:Builder.io 可与支持 SSR 和 SSG 的各种框架配合使用。
  2. 自动优化:构建器优化内容的性能,包括代码分割和屏幕外组件的延迟加载。
  3. 动态渲染:您可以根据用户属性或 A/B 测试渲染不同的内容,同时保持 SEO 优势。
  4. 轻松集成:Builder 提供 SDK 和文档来无缝集成您现有的项目。

实施示例

以下是如何使用 Builder 和 Next.js 在服务器端获取和呈现内容的基本示例:

import { builder, BuilderComponent } from '@builder.io/react'

builder.init('YOUR_API_KEY')

export async function getStaticProps({ params }) {
const page = await builder
.get('page', {
userAttributes: {
urlPath: '/' + (params?.page?.join('/') || '')
}
})
.toPromise()

return {
props: {
page: page || null
},
revalidate: 5
}
}

export default function Page({ page }) {
return <BuilderComponent model="page" content={page} />
}

最佳实践

  1. 确保您使用的框架支持 SSR 或 SSG。
  2. 集成构建器页面或部分时,请遵循框架的准则来获取服务器端数据。
  3. 有关处理服务器端数据的更多信息,请参阅getAsyncProps自述文件。

通过利用 Builder for SSR,您可以将headless CMS 的灵活性与服务器端渲染的性能优势结合起来,同时保持易于使用的可视化编辑体验。

总结

服务器端渲染 (SSR) 是 Web 开发中的一种强大方法,可以显着增强应用程序的性能、SEO 和用户体验。在本文中,我们探讨了 SSR 是什么、它与客户端渲染有何不同、它对搜索引擎的影响以及使用 Next.js 等流行框架的实际实施策略。

我们还讨论了完全渲染页面的概念,并研究了不同生态系统中的各种 SSR 解决方案。虽然 SSR 提供了许多好处,但在决定是否实施它时,考虑项目的具体需求非常重要。

FAQ 常问问题

  1. 问:SSR 如何影响我的开发工作流程?

    答:SSR 会使开发变得更加复杂,因为您需要同时考虑服务器和客户端环境。您可能需要调整构建过程并对特定于浏览器的 API 保持谨慎。

  2. 问:SSR 如何影响我网站的交互时间 (TTI)?

    答:虽然 SSR 可以提高初始内容的可见性,但它可能会稍微延迟 TTI,因为浏览器需要在收到初始 HTML 后加载并混合 JavaScript。

  3. 问:SSR 是否有特定的安全注意事项?

    答:是的,使用 SSR,您需要更加小心地暴露服务器端的敏感数据或 API。始终清理用户输入并谨慎对待初始渲染中包含的数据。

  4. 问:SSR 如何与身份验证和个性化内容配合使用?

    答:SSR 可以与身份验证配合使用,但需要小心处理。您可能需要实施 JWT 令牌或服务器端会话等技术来管理经过身份验证的 SSR 请求。