聊聊React SSR
在现代 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']
}
}
];
详细步骤解释
- 下载 JavaScript: 当用户访问页面时,服务器返回包含 React 组件静态标记的 HTML。浏览器开始解析 HTML 并构建 DOM,同时开始下载
<script src="/bundle.js"></script>
中指定的 JavaScript 文件。 - 执行 JavaScript: JavaScript 文件下载完成后,浏览器执行这个文件。
ReactDOM.hydrate()
方法会被调用,它接管由服务器渲染的应用,hydrate的入参是跟server.js的App同一个组件进行绑定。并重新利用已有的 DOM。 - 绑定事件: 在 Hydration 过程中,React 将事件处理器绑定到对应的元素上。现在,当用户点击“Increment”按钮时,
setCount
函数将被触发,React 更新 DOM 来反映新的状态。
结论
通过结合 SSR 和客户端 Hydration,开发者可以创建既快速又交互性强的 Web 应用。这种技术不仅提升了用户体验,还有助于提高应用的可访问性和搜索引擎排名。虽然实现起来比纯客户端渲染复杂,但在需要快速首屏加载和良好 SEO 的应用中,这种付出是值得的。
希望本文能帮助你更好地理解和实现 React 的 SSR 和客户端激活。如果你有任何疑问或想要深入讨论,欢迎留言交流。
转载自:https://juejin.cn/post/7360892717545488393