likes
comments
collection
share

聊聊React SSR

作者站长头像
站长
· 阅读数 33

在现代 Web 开发中,提高网站的性能和搜索引擎优化(SEO)始终是核心议题。React 的服务端渲染(SSR)配合客户端激活(Hydration)提供了一个优雅的解决方案。本文将详细介绍这一流程,帮助开发者理解其原理及实现方式。

什么是 React SSR?

React SSR 是一种技术,其中 React 组件在服务器上被渲染成 HTML 字符串,然后发送到客户端。这种方式相较于传统的全部客户端渲染(CSR),可以显著提高首次加载的速度,并改善应用的 SEO。

客户端激活(Hydration)的作用

Hydration 是一个过程,在此过程中,React 在客户端接管由服务器渲染的 HTML,并添加事件监听器和其他必要的前端逻辑,使静态内容变得动态可交互。这是 SSR 和 CSR 结合的关键步骤,确保了应用既能快速显示内容,又具备丰富的用户交互性。

实现 React SSR 和 Hydration 的流程

首先,我们创建一个 React 组件,该组件即用于server.js,也用于client.js

// src/App.js
import React, { useState } from 'react';

function App() {
  const [count, setCount] = useState(0); // 初始化计数器为 0

  return (
    <div>
      <h1>Hello, SSR!</h1>
      <p>Count: {count}</p>
      <button onClick={() => setCount(count + 1)}>Increment</button>
    </div>
  );
}

export default App;

服务器端代码

接着,我们在服务器端使用这个组件来进行渲染:

// src/server.js
import express from 'express';
import React from 'react';
import ReactDOMServer from 'react-dom/server';
import App from './App';

const app = express();
const PORT = 3000;

app.use(express.static('public'));  // 静态文件目录

app.get('/', (req, res) => {
  const appString = ReactDOMServer.renderToString(<App />);

  // 返回 HTML 结构
  res.send(`
    <!DOCTYPE html>
    <html lang="en">
    <head>
      <meta charset="UTF-8">
      <title>React SSR</title>
    </head>
    <body>
      <div id="root">${appString}</div>
      <script src="/bundle.js"></script>  <!-- 引入客户端的 JavaScript -->
    </body>
    </html>
  `);
});

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

客户端代码

客户端的 JavaScript 需要在 src 目录下创建一个入口文件,这个文件会处理客户端的 Hydration 过程。

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

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

Webpack 配置

我们还需要配置 Webpack 来打包客户端和服务器的代码:

// webpack.config.js
const path = require('path');
const nodeExternals = require('webpack-node-externals');

module.exports = [
  {
    entry: './src/client.js',
    output: {
      path: path.resolve(__dirname, 'public'),
      filename: 'bundle.js'
    },
    module: {
      rules: [{ test: /.jsx?$/, use: 'babel-loader' }]
    },
    resolve: {
      extensions: ['.js', '.jsx']
    }
  },
  {
    entry: './src/server.js',
    target: 'node',
    externals: [nodeExternals()],
    output: {
      path: path.resolve(__dirname, 'build'),
      filename: 'server.js'
    },
    module: {
      rules: [{ test: /.jsx?$/, use: 'babel-loader' }]
    },
    resolve: {
      extensions: ['.js', '.jsx']
    }
  }
];

详细步骤解释

  1. 下载 JavaScript: 当用户访问页面时,服务器返回包含 React 组件静态标记的 HTML。浏览器开始解析 HTML 并构建 DOM,同时开始下载 <script src="/bundle.js"></script> 中指定的 JavaScript 文件。
  2. 执行 JavaScript: JavaScript 文件下载完成后,浏览器执行这个文件。ReactDOM.hydrate() 方法会被调用,它接管由服务器渲染的应用,hydrate的入参是跟server.js的App同一个组件进行绑定。并重新利用已有的 DOM。
  3. 绑定事件: 在 Hydration 过程中,React 将事件处理器绑定到对应的元素上。现在,当用户点击“Increment”按钮时,setCount 函数将被触发,React 更新 DOM 来反映新的状态。

结论

通过结合 SSR 和客户端 Hydration,开发者可以创建既快速又交互性强的 Web 应用。这种技术不仅提升了用户体验,还有助于提高应用的可访问性和搜索引擎排名。虽然实现起来比纯客户端渲染复杂,但在需要快速首屏加载和良好 SEO 的应用中,这种付出是值得的。

希望本文能帮助你更好地理解和实现 React 的 SSR 和客户端激活。如果你有任何疑问或想要深入讨论,欢迎留言交流。

转载自:https://juejin.cn/post/7360892717545488393
评论
请登录