We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
服务端渲染(SSR)是一种用于处理页面的技术,它在服务器端构建HTML结构并将完整的交互式页面发送到浏览器,然后将状态和事件绑定到该页面。SSR主要解决了两个关键问题:
搜索引擎爬虫可以直接查看完全渲染的页面,而客户端渲染(Client-Side Rendering,简称CSR)可能会导致搜索引擎无法获取页面内容。
CSR可能导致首屏白屏,用户体验较差。SSR可以在服务器端渲染首屏,提高加载速度。
我们通过Express创建一个服务器,用于监听3000端口的请求,并在根目录请求时返回HTML页面。
const express = require('express'); const app = express(); app.get('/', (req, res) => { res.send(` <html> <head> <title>SSR Demo</title> </head> <body> Hello world </body> </html> `); }); app.listen(3000, () => console.log('Example app listening on port 3000!'));
我们将在服务器端编写React代码,并在app.js中引用它。
app.js
为了使服务器能够识别JSX,我们需要使用Webpack对项目进行打包转换。创建一个名为webpack.server.js的配置文件,并进行相关配置。
webpack.server.js
const path = require('path'); const nodeExternals = require('webpack-node-externals'); module.exports = { target: 'node', mode: 'development', entry: './app.js', output: { filename: 'bundle.js', path: path.resolve(__dirname, 'build'), }, externals: [nodeExternals()], module: { rules: [ { test: /\.js?$/, loader: 'babel-loader', exclude: /node_modules/, options: { presets: ['react', 'stage-0', ['env', { targets: { browsers: ['last 2 versions'] } }]], }, }, ], }, };
renderToString
我们借助react-dom提供的renderToString方法,将React组件渲染为HTML字符串。
react-dom
import express from 'express'; import React from 'react'; import { renderToString } from 'react-dom/server'; import Home from './src/containers/Home'; const app = express(); const content = renderToString(<Home />); app.get('/', (req, res) => { res.send(` <html> <head> <title>SSR Demo</title> </head> <body> ${content} </body> </html> `); }); app.listen(3001, () => console.log('Example app listening on port 3001!'));
同构是指一套React代码在服务器端和客户端都能运行。在同构中,服务端渲染完成页面结构,而浏览器端渲染完成事件绑定和一些交互。这种方式既可以提高首屏加载速度,又能保持页面的交互性。
在React应用中,通常会存在多个页面和路由的情况。为了在服务端渲染中处理路由,需要配置路由信息。
:
import React from 'react'; import { Route } from 'react-router-dom'; import Home from './containers/Home'; export default ( <div> <Route path="/" exact component={Home}></Route> </div> );
然后,可以通过index.js引用路由信息:
index.js
import React from 'react'; import ReactDom from 'react-dom'; import { BrowserRouter } from 'react-router-dom'; import Router from '../Routers'; const App = () => { return ( <BrowserRouter> {Router} </BrowserRouter> ); }; ReactDom.hydrate(<App />, document.getElementById('root'));
在服务端渲染时,每个Route组件外面包裹着一层div,但在服务端返回的代码中并没有这个div。这可能会导致浏览器端渲染时出现问题。为了解决这个问题,我们需要在服务端执行一遍路由信息,使用StaticRouter来替代BrowserRouter,并通过context参数进行参数传递。
StaticRouter
BrowserRouter
context
import express from 'express'; import React from 'react'; import { renderToString } from 'react-dom/server'; import { StaticRouter } from 'react-router-dom'; import Router from '../Routers'; const app = express(); app.use(express.static('public')); app.get('/', (req, res) => { const content = renderToString( <StaticRouter location={req.path} context={{}}> {Router} </StaticRouter> ); res.send(` <html> <head> <title>SSR Demo</title> </head> <body> <div id="root">${content}</div> <script src="/index.js"></script> </body> </html> `); }); app.listen(3001, () => console.log('Example app listening on port 3001!'));
props
store
renderToString()
The text was updated successfully, but these errors were encountered:
No branches or pull requests
服务端渲染(SSR)
服务端渲染简介
服务端渲染的问题
SEO问题
首屏加载问题
实现服务端渲染(SSR)
创建Express服务器
我们将在服务器端编写React代码,并在
app.js
中引用它。使用Webpack进行打包
使用
renderToString
渲染React组件实现服务端和客户端共用一套代码
同构概念
处理路由问题
:
然后,可以通过
index.js
引用路由信息:解决路由渲染问题
服务端渲染的工作流程
props
、context
或store
等形式传递给React组件。renderToString()
将React组件渲染为HTML字符串。参考文献
The text was updated successfully, but these errors were encountered: