如何在 React 项目中进行服务器端渲染(SSR),它有什么优势

大白话如何在 React 项目中进行服务器端渲染(SSR),它有什么优势

什么是服务器端渲染(SSR)

在传统的 React 项目里,页面的渲染工作是在浏览器里完成的。也就是当你访问一个网页时,浏览器会先下载 HTML、CSS 和 JavaScript 文件,接着运行 JavaScript 代码来生成页面内容。而服务器端渲染(SSR)则是让服务器先把 React 组件渲染成 HTML 字符串,再把这个 HTML 字符串发送给浏览器。这样一来,浏览器就能直接显示已经渲染好的页面,不用再等待 JavaScript 代码运行了。

SSR 的优势

  1. 更快的初始加载速度:因为浏览器拿到的是已经渲染好的 HTML,所以能更快地显示页面内容,减少用户等待时间。
  2. 更好的 SEO:搜索引擎爬虫可以直接读取服务器返回的 HTML 内容,有利于网站在搜索引擎中的排名。
  3. 更好的用户体验:特别是在网络较慢的情况下,用户能更快地看到页面内容,提升体验。

如何在 React 项目中进行 SSR

下面我会一步步教你如何在 React 项目中实现 SSR。

1. 创建 React 项目

首先,你得创建一个新的 React 项目。可以使用 create-react-app 来创建:

bash 复制代码
npx create-react-app my-ssr-app
cd my-ssr-app
2. 安装必要的依赖

我们需要安装一些额外的依赖,像 express 用于创建服务器,react-dom/server 用于在服务器端渲染 React 组件。

bash 复制代码
npm install express react-dom
3. 修改项目结构

在项目根目录下创建一个 server.js 文件,这个文件将用于创建服务器和处理 SSR。

4. 编写 server.js 文件

下面是 server.js 文件的详细代码,每一行都有注释:

javascript 复制代码
// 引入 express 模块,用于创建服务器
const express = require('express');
// 创建一个 express 应用实例
const app = express();
// 引入 React 库
const React = require('react');
// 引入 ReactDOMServer 用于在服务器端渲染 React 组件
const ReactDOMServer = require('react-dom/server');
// 引入 App 组件,这里假设你的主组件是 App
const App = require('./src/App').default;

// 处理根路径的请求
app.get('/', (req, res) => {
    // 使用 ReactDOMServer.renderToString 方法将 App 组件渲染成 HTML 字符串
    const html = ReactDOMServer.renderToString(<App />);
    // 定义一个完整的 HTML 页面模板,将渲染好的 HTML 字符串插入到模板中
    const page = `
        <!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>
            <!-- 插入渲染好的 HTML 字符串 -->
            <div id="root">${html}</div>
            <!-- 引入客户端的 JavaScript 文件 -->
            <script src="/static/js/bundle.js"></script>
        </body>
        </html>
    `;
    // 将完整的 HTML 页面发送给客户端
    res.send(page);
});

// 监听 3001 端口,启动服务器
const port = 3001;
app.listen(port, () => {
    console.log(`Server is running on port ${port}`);
});
5. 修改 src/index.js 文件

src/index.js 文件中,我们需要使用 hydrateRoot 方法来将服务器端渲染的 HTML 与客户端的 React 代码进行关联。

javascript 复制代码
// 引入 React 库
import React from 'react';
// 引入 ReactDOM 用于在客户端渲染 React 组件
import ReactDOM from 'react-dom/client';
// 引入 App 组件
import App from './App';

// 获取 id 为 root 的 DOM 元素
const rootElement = document.getElementById('root');
// 使用 hydrateRoot 方法将服务器端渲染的 HTML 与客户端的 React 代码进行关联
const root = ReactDOM.hydrateRoot(rootElement, <App />);
6. 运行项目

首先,启动服务器:

bash 复制代码
node server.js

然后,在浏览器中访问 http://localhost:3001,你就可以看到已经使用 SSR 渲染的页面了。

总结

通过以上步骤,你就可以在 React 项目中实现服务器端渲染(SSR)了。SSR 能带来更快的初始加载速度、更好的 SEO 和用户体验。希望这个教程能帮助你理解和实现 SSR。

如何优化React项目的服务器端渲染性能?

在 React 项目里,优化服务器端渲染(SSR)性能可从多方面着手,下面是一些实用的优化方法和对应的代码示例。

1. 代码分割

代码分割能减少初始加载的 JavaScript 代码量,让页面更快加载。在 React 中,可使用 React.lazySuspense 来实现。

jsx 复制代码
// 假设这是你的路由配置文件
import React, { lazy, Suspense } from 'react';
import { BrowserRouter as Router, Routes, Route } from 'react-router-dom';

// 懒加载组件
const Home = lazy(() => import('./pages/Home'));
const About = lazy(() => import('./pages/About'));

const App = () => {
    return (
        <Router>
            <Suspense fallback={<div>Loading...</div>}>
                <Routes>
                    <Route path="/" element={<Home />} />
                    <Route path="/about" element={<About />} />
                </Routes>
            </Suspense>
        </Router>
    );
};

export default App;

上述代码借助 React.lazy 来懒加载组件,Suspense 则在组件加载期间显示加载提示。

2. 缓存机制

使用缓存可避免对相同内容的重复渲染,提升服务器性能。在 Node.js 服务器中,可使用 lru-cache 来实现简单的缓存。

javascript 复制代码
const express = require('express');
const React = require('react');
const ReactDOMServer = require('react-dom/server');
const LRU = require('lru-cache');
const App = require('./src/App').default;

const app = express();
// 创建一个 LRU 缓存实例,最大缓存项数为 100
const cache = new LRU({ max: 100 });

app.get('/', (req, res) => {
    const cacheKey = req.url;
    // 检查缓存中是否存在该 URL 的渲染结果
    if (cache.has(cacheKey)) {
        const cachedHtml = cache.get(cacheKey);
        return res.send(cachedHtml);
    }

    const html = ReactDOMServer.renderToString(<App />);
    // 将渲染结果存入缓存
    cache.set(cacheKey, html);
    res.send(`
        <!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">${html}</div>
            <script src="/static/js/bundle.js"></script>
        </body>
        </html>
    `);
});

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

此代码利用 lru-cache 来缓存渲染结果,若缓存中存在请求的 URL 对应的渲染结果,就直接返回缓存内容。

3. 异步数据获取优化

在 SSR 中,异步数据获取是性能瓶颈之一。可使用 React QuerySWR 等库来优化数据获取。

jsx 复制代码
import React from 'react';
import { useQuery } from 'react-query';

// 模拟异步数据获取函数
const fetchData = async () => {
    const response = await fetch('https://api.example.com/data');
    return response.json();
};

const MyComponent = () => {
    // 使用 useQuery 进行数据获取
    const { data, isLoading, error } = useQuery('myData', fetchData);

    if (isLoading) return <div>Loading...</div>;
    if (error) return <div>Error: {error.message}</div>;

    return (
        <div>
            {data.map(item => (
                <div key={item.id}>{item.name}</div>
            ))}
        </div>
    );
};

export default MyComponent;

上述代码使用 React QueryuseQuery 钩子来进行数据获取,它会自动处理缓存、重试等操作。

4. 服务器优化

合理配置服务器资源也很关键,可使用 pm2 来管理 Node.js 进程,保证服务器的高可用性和性能。

bash 复制代码
# 全局安装 pm2
npm install -g pm2
# 使用 pm2 启动服务器
pm2 start server.js

5. 优化 CSS 加载

采用 CSS-in-JS 或 extract-text-webpack-plugin 等工具,将 CSS 提取到单独的文件中,避免内联 CSS 带来的性能问题。

javascript 复制代码
// 在 webpack 配置中使用 MiniCssExtractPlugin 提取 CSS
const MiniCssExtractPlugin = require('mini-css-extract-plugin');

module.exports = {
    // 其他配置...
    module: {
        rules: [
            {
                test: /\.css$/,
                use: [
                    MiniCssExtractPlugin.loader,
                    'css-loader'
                ]
            }
        ]
    },
    plugins: [
        new MiniCssExtractPlugin({
            filename: '[name].[contenthash].css'
        })
    ]
};

上述代码借助 MiniCssExtractPlugin 把 CSS 提取到单独的文件中。

通过以上这些方法,能显著优化 React 项目的服务器端渲染性能。

相关推荐
崔庆才丨静觅2 小时前
hCaptcha 验证码图像识别 API 对接教程
前端
passerby60613 小时前
完成前端时间处理的另一块版图
前端·github·web components
掘了3 小时前
「2025 年终总结」在所有失去的人中,我最怀念我自己
前端·后端·年终总结
崔庆才丨静觅3 小时前
实用免费的 Short URL 短链接 API 对接说明
前端
崔庆才丨静觅4 小时前
5分钟快速搭建 AI 平台并用它赚钱!
前端
崔庆才丨静觅4 小时前
比官方便宜一半以上!Midjourney API 申请及使用
前端
Moment4 小时前
富文本编辑器在 AI 时代为什么这么受欢迎
前端·javascript·后端
崔庆才丨静觅5 小时前
刷屏全网的“nano-banana”API接入指南!0.1元/张量产高清创意图,开发者必藏
前端
剪刀石头布啊5 小时前
jwt介绍
前端
爱敲代码的小鱼5 小时前
AJAX(异步交互的技术来实现从服务端中获取数据):
前端·javascript·ajax