首屏等待
在 SPA 模式下,所有的数据请求和 DOM 渲染都在浏览器端完成,所以当我们第一次访问页面的时候很可能会存在“白屏”等待,而服务端渲染所有数据和 html 内容已在服务端处理完成,浏览器收到的是完整的 html 内容,可以更快地看到渲染内容,在服务端完成数据请求肯定要比浏览器端效率高得多。
SEO
SPA 由于加载模版的时候页面骨架上面只有一个节点,其余所有节点都是由 JS 动态生成的,因为搜索引擎爬虫只认识 html 结构的内容,不能识别 JS 代码内容,所以对于 SEO,完全无能为力。
核心原理
整体来说服务端渲染原理不复杂,核心内容就是同构。
node server 接收到客户端请求,得到当前的 req url path,然后在已有的路有列表内查找对应的组件,拿到需要请求去的数据,将数据作为 props、context 或者 store 形式存入组件,然后基于 react 内置的服务端渲染 api renderToString
或者 renderToNodeStream
把组件渲染为 html字符串 或者 stream流,在把最终的 html 进行输出前需要将数据注入到浏览器端(注水),server 输出(response)后浏览器可以得到数据(脱水),浏览器开始进行渲染和节点比对,然后执行组件的 componentDidMount 完成组件内事件绑定和一些交互,浏览器重用了服务端输出的 html节点,整个流程结束。
![cd18f548d0429c343ff76eba4c5995ea.png](https://i-blog.csdnimg.cn/blog_migrate/bcd03be6640bda382ba1aa7bb49fa9dd.png)
React SSR
从 ejs 开始
实现 ssr 很简单,先看一个 node ejs 的例子
html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title><%= title %>title>
head>
<body>
<%= data %>
body>
html>
// node ssr
const ejs = require('ejs')
const http = require('http')
http.createServer((rea, res) => {
if(req.url === '/') {
res.writeHead(200, {
'Content-Type': 'text/html'
})
ejs.renderFile('./views/index.ejs', {
title: 'react ssr',
data: '首页'
}, (err, data) => {
if(err) console.log(err)
else res.end(data)
})
}
}).listen(8080)
JSX 到字符串
参考上面,我们使用 React 组建来实现服务端渲染,使用 jsx 来代替 ejs。
const React = require('react')
const { renderToString } = require('react-dom/server')
const http = require('http')
// 组件
class App extends React.Component {
render() {
return <h1>{this.props.data.title}h1>
}
}
// 模拟数据获取
const fetch = function() {
return {
title: 'react ssr',
data: []
}
}
http.createServer((req, res) => {
if(req.url === '/') {
res.writeHead(200, {
'Content-Type': 'text/html'
})
const data &