# 服务端渲染(SSR)
Support in 2.8.0+# 介绍
# 什么是服务端渲染
服务端渲染(Server-Side Render),是指将单页应用(SPA)在服务器端渲染为 HTML 片段,发送到浏览器,然后为其绑定状态与事件,成为完全可交互页面的过程。
# 与客户端渲染的区别
后续简称服务端渲染为 SSR,客户端渲染为 CSR
如下图所示:
SSR 优势在于:
- 更友好的 SEO:爬虫可以直接抓取渲染之后的页面,CSR 首次返回的 HTML 文档中,是空节点(root),不包含内容。而 SSR 返回渲染之后的 HTML 片段,内容完整,所以能更好地被爬虫分析与索引。
- 更快的首屏加载速度:无需等待 JavaScript 完成下载且执行才显示内容,更快速地看到完整渲染的页面。有更好的用户体验。
- 需要服务端支持:Umijs 主要关注是应用 UI 层渲染,完成 SSR 需要服务端(例如:Node.js)支持。
# Umi SSR 特性
- 服务端框架无关
- 支持 CSS Modules
- 支持 TypeScript
- 支持本地开发 HMR
- 支持 dva
- 支持 Serverless
# 使用
# Umi 配置
export default {
ssr: true,
};
开启后,运行 umi build
,会生成如下文件:
.
├── dist
│ ├── index.html
│ ├── ssr-client-mainifest.json
│ ├── umi.css
│ ├── umi.js
│ └── umi.server.js
# 服务端
由于与服务端框架无关,Umi 关注是应用 UI 层渲染,与服务端框架不耦合。
为了降低服务端框架接入门槛,Umi 提供 umi-server,并以常见的 Node.js 服务端框架(Koajs、Express、Egg.js)为例,给出具体接入方式。
# 使用原生 http 模块
用 Node.js 原生 http 模块做服务端渲染。
// bar.js
const server = require('umi-server');
const http = require('http');
const { createReadStream } = require('fs');
const { join, extname } = require('path');
const root = join(__dirname, 'dist');
const render = server({
root,
})
const headerMap = {
'.js': 'text/javascript',
'.css': 'text/css',
'.jpg': 'image/jpeg',
'.png': 'image/jpeg',
}
http.createServer(async (req, res) => {
const ext = extname(req.url);
const header = {
'Content-Type': headerMap[ext] || 'text/html'
}
res.writeHead(200, header);
if (!ext) {
// url render
const ctx = {
req,
res,
}
const { ssrHtml } = await render(ctx);
res.write(ssrHtml);
res.end()
} else {
// static file url
const path = join(root, req.url);
const stream = createReadStream(path);
stream.on('error', (error) => {
res.writeHead(404, 'Not Found');
res.end();
});
stream.pipe(res);
}
}).listen(3000)
console.log('http://localhost:3000');
运行 node bar.js
,访问 http://localhost:3000,就是一个简单的服务端渲染例子。详细可见 examples/normal
# Koa.js
可参考 examples/koajs
# Egg.js
可参考 examples/eggjs
# 预渲染(Pre Render)
预渲染(Pre Render)在构建时执行渲染,将渲染后的 HTML 片段生成静态 html 文件。无需使用 web 服务器实时动态编译 HTML,适用于静态站点。
Umi 提供 @umijs/plugin-prerender 插件,帮助用户在构建时预渲染出页面。更多用法参考文档。
export default {
plugins: [['@umijs/plugin-prerender', options]],
};
# 常见问题
见 FAQ