React Server Side Rendering (SSR) 详解

本文涉及的产品
云原生网关 MSE Higress,422元/月
函数计算FC,每月15万CU 3个月
可观测监控 Prometheus 版,每月50GB免费额度
简介: 【10月更文挑战第19天】React Server Side Rendering (SSR) 是一种在服务器端渲染 React 应用的技术,通过在服务器上预先生成 HTML 内容,提高首屏加载速度和 SEO。本文从概念入手,逐步探讨 SSR 的实现步骤、常见问题及解决方案,并通过代码示例进行说明。

React Server Side Rendering (SSR) 是一种在服务器端渲染 React 应用的技术。通过 SSR,可以在服务器上预先生成 HTML 内容,然后发送给客户端,从而提高首屏加载速度和搜索引擎优化 (SEO)。本文将从概念入手,逐步深入探讨 SSR 的常见问题、易错点及如何避免,并通过代码案例进行说明。
image.png

一、React SSR 的概念

1. 什么是 SSR?

定义:Server Side Rendering (SSR) 是一种在服务器端生成 HTML 标记的技术,然后将这些标记发送到客户端浏览器。客户端浏览器接收到 HTML 后,再进行后续的 JavaScript 加载和执行。

优点

  • 首屏加载速度快:用户可以更快地看到页面内容,提升用户体验。
  • SEO 友好:搜索引擎爬虫可以直接抓取到完整的 HTML 内容,提高搜索引擎排名。
  • 减少初始加载时间:客户端只需要下载少量的 JavaScript 代码,减少了首次加载的时间。

2. 为什么需要 SSR?

传统的单页应用 (SPA) 在首次加载时,客户端需要下载大量的 JavaScript 代码,然后才能渲染出页面内容。这会导致首屏加载时间较长,尤其是在网络条件较差的情况下。而 SSR 可以在服务器端预先生成 HTML,从而显著提高首屏加载速度。

二、React SSR 的实现

1. 基本步骤

  1. 创建 React 应用:使用 create-react-app 或其他工具创建一个 React 应用。
  2. 设置服务器:使用 Node.js 和 Express 创建一个服务器。
  3. 渲染 React 组件:在服务器上使用 ReactDOMServer.renderToString 方法将 React 组件转换为 HTML 字符串。
  4. 发送 HTML 到客户端:将生成的 HTML 发送到客户端浏览器。
  5. 客户端 hydration:客户端接收到 HTML 后,使用 ReactDOM.hydrate 方法将静态 HTML 转换为可交互的 React 应用。

2. 代码示例

2.1 创建 React 应用

首先,使用 create-react-app 创建一个简单的 React 应用:

npx create-react-app my-ssr-app
cd my-ssr-app

2.2 设置服务器

安装必要的依赖:

npm install express react react-dom

创建一个 server.js 文件:

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

const app = express();
const PORT = process.env.PORT || 3000;

app.use(express.static(path.join(__dirname, 'build')));

app.get('*', (req, res) => {
   
  const html = `
    <!DOCTYPE html>
    <html lang="en">
      <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>My SSR App</title>
      </head>
      <body>
        <div id="root">${
     ReactDOMServer.renderToString(<App />)}</div>
        <script src="/static/js/main.js"></script>
      </body>
    </html>
  `;
  res.send(html);
});

app.listen(PORT, () => {
   
  console.log(`Server is running on port ${
     PORT}`);
});

2.3 客户端 hydration

public/index.html 中,确保有以下内容:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>My SSR App</title>
  </head>
  <body>
    <div id="root"></div>
    <script src="/static/js/main.js"></script>
  </body>
</html>

src/index.js 中,使用 hydrate 方法:

import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';

ReactDOM.hydrate(
  <React.StrictMode>
    <App />
  </React.StrictMode>,
  document.getElementById('root')
);

三、常见问题与易错点

1. 数据获取问题

问题:在 SSR 中,数据获取通常需要在服务器端完成,然后再传递给 React 组件。

解决方案:使用 getInitialProps 方法在服务器端获取数据,并将其传递给组件。

// src/App.js
import React from 'react';

class App extends React.Component {
   
  static async getInitialProps({
    req }) {
   
    const userAgent = req ? req.headers['user-agent'] : navigator.userAgent;
    return {
    userAgent };
  }

  render() {
   
    return (
      <div>
        <h1>Hello, World!</h1>
        <p>User Agent: {
   this.props.userAgent}</p>
      </div>
    );
  }
}

export default App;

2. CSS-in-JS 问题

问题:使用 CSS-in-JS 库(如 styled-components)时,样式可能不会在服务器端正确注入。

解决方案:使用 ServerStyleSheet 来捕获服务器端的样式,并将其注入到 HTML 中。

// server.js
const {
    ServerStyleSheet } = require('styled-components');

app.get('*', (req, res) => {
   
  const sheet = new ServerStyleSheet();
  const html = `
    <!DOCTYPE html>
    <html lang="en">
      <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>My SSR App</title>
        ${
     sheet.getStyleTags()}
      </head>
      <body>
        <div id="root">${
     ReactDOMServer.renderToString(sheet.collectStyles(<App />))}</div>
        <script src="/static/js/main.js"></script>
      </body>
    </html>
  `;
  sheet.seal();
  res.send(html);
});

3. 路由问题

问题:在 SSR 中,路由匹配需要在服务器端完成,否则可能会出现 404 错误。

解决方案:使用 react-routermatchPath 方法来匹配路由。

// server.js
const {
    matchPath } = require('react-router-dom');
const routes = require('./src/routes');

app.get('*', (req, res) => {
   
  const sheet = new ServerStyleSheet();
  const context = {
   };

  const activeRoute = routes.find(route => matchPath(req.url, route));
  if (activeRoute) {
   
    const html = `
      <!DOCTYPE html>
      <html lang="en">
        <head>
          <meta charset="UTF-8">
          <meta name="viewport" content="width=device-width, initial-scale=1.0">
          <title>My SSR App</title>
          ${
     sheet.getStyleTags()}
        </head>
        <body>
          <div id="root">${
     ReactDOMServer.renderToString(sheet.collectStyles(<activeRoute.component {
     ...context} />))}</div>
          <script src="/static/js/main.js"></script>
        </body>
      </html>
    `;
    sheet.seal();
    res.send(html);
  } else {
   
    res.status(404).send('Not Found');
  }
});

四、如何避免常见问题

1. 代码规范与文档

  • 代码规范:制定并遵守统一的代码规范,确保代码的可读性和可维护性。
  • 文档:编写详细的接口文档和测试文档,方便开发和测试人员理解系统结构和测试要求。

2. 单元测试与集成测试

  • 单元测试:编写单元测试,确保每个组件的功能正确。
  • 集成测试:编写集成测试,验证组件间的交互。

3. 持续集成与持续交付

  • 持续集成:使用 CI/CD 工具(如 Jenkins、GitHub Actions)自动化构建和测试过程,确保每次提交都能及时发现问题。
  • 持续交付:确保测试通过后可以自动部署到测试环境,加快反馈循环。

五、总结

React Server Side Rendering (SSR) 是一种强大的技术,可以显著提高首屏加载速度和 SEO 效果。通过本文的介绍,希望读者能够对 SSR 有更深入的理解,并掌握一些常见的问题及其解决方案。在实际开发中,合理运用这些方法和技术,可以有效提升应用的性能和用户体验。

目录
相关文章
|
3天前
|
前端开发 JavaScript 搜索推荐
一文 Next / React / SSR / SSG / CSR 扫盲
一文 Next / React / SSR / SSG / CSR 扫盲
|
4月前
|
前端开发 JavaScript 算法
React Server Component 使用问题之想在路由切换时保持客户端状态,如何实现
React Server Component 使用问题之想在路由切换时保持客户端状态,如何实现
|
4月前
|
前端开发 JavaScript PHP
React Server Component 使用问题之路由的能力,如何实现
React Server Component 使用问题之路由的能力,如何实现
|
4月前
|
前端开发 JavaScript
React Server Component 使用问题之添加jsx的组件化能力,如何操作
React Server Component 使用问题之添加jsx的组件化能力,如何操作
|
4月前
|
前端开发 PHP 开发者
React Server Component 使用问题之怎么使用Docker运行PHP应用
React Server Component 使用问题之怎么使用Docker运行PHP应用
|
4月前
|
开发者
🔥揭秘JSF导航:如何轻松驾驭页面跳转与流程控制?🎯
【8月更文挑战第31天】在 JavaServer Faces(JSF)中,导航规则是控制页面跳转和流程的关键。本文详细介绍 JSF 的导航规则,包括转发和重定向等跳转方式,并通过 `faces-config.xml` 文件配置示例展示如何实现不同场景下的页面跳转及流程控制,帮助开发者有效管理应用程序的页面流和用户交互,提升应用质量。
58 0
|
4月前
|
前端开发 搜索推荐 UED
React Server Side Rendering的神奇之处:如何用SSR提升SEO与首屏加载速度,让你的项目一鸣惊人?
【8月更文挑战第31天】在现代Web开发中,React服务器端渲染(SSR)能显著提升SEO性能和首屏加载速度。通过在服务器端预渲染组件并发送HTML至客户端,SSR不仅优化了首屏加载时间,增强了用户体验,还生成了便于搜索引擎抓取的静态HTML文件,提升了页面排名。此外,SSR还具备提高安全性的优点,能够有效防范XSS攻击。虽然其开发复杂性和服务器负载是潜在劣势,但借助如Next.js等库、编写高效组件及定期维护等最佳实践,可以充分发挥SSR的优势,为未来Web开发注入更强动力。
66 0
|
4月前
|
前端开发 JavaScript 开发者
React Server Component 使用问题之为什么选择使用 React 官方的 renderToString 来渲染 HTML,如何解决
React Server Component 使用问题之为什么选择使用 React 官方的 renderToString 来渲染 HTML,如何解决
|
6月前
|
前端开发 JavaScript API
react next ssr
react next ssr
|
6月前
|
前端开发 JavaScript 算法
RSC 就是套壳 PHP ?带你从零实现 React Server Component
RSC 就是套壳 PHP ?带你从零实现 React Server Component