什么是服务器端渲染 (SSR)
在单页面应用 (SPA) 中,前端代码运行在浏览器中,浏览器通过 Ajax 等方式从服务器上请求数据,最终将数据渲染为页面。这样的前后端分离在开发效率和用户体验上都有很好的表现。但是这种方式也存在一些问题,比如首屏加载速度慢、SEO 不友好等。为了解决这些问题,服务器端渲染 (SSR) 应运而生。
与 SPA 不同,SSR 的渲染过程发生在服务器端。服务器将数据和 HTML 模板整合,最终输出给浏览器的是完整的 HTML 页面。这样就可以避免首屏加载速度慢的问题,同时搜索引擎也可以正常抓取网站内容,提高了 SEO 友好度。
使用 JavaScript 框架的服务器端渲染
1. React SSR
React 是一个流行的 JavaScript 库,它已经发展成为前端开发的首选框架之一。React 也可以用于服务器端渲染,通过 ReactDOMServer 与 Node.js 集成。以下是一个 React SSR 的示例:
import React from 'react';
import { renderToString } from 'react-dom/server';
import App from './App';
const express = require('express');
const app = express();
app.get('/', (req, res) => {
const html = renderToString(<App />);
res.send(`
<html>
<head>
<title>React SSR Demo</title>
</head>
<body>
<div id="root">${html}</div>
<script src="bundle.js"></script>
</body>
</html>
`);
});
app.listen(3000, () => {
console.log('Server is listening on port 3000');
});
上面的代码中,我们通过 renderToString 将 React 组件转换为字符串,然后通过 express 发送完整的 HTML 页面。这里的 HTML 模板可以根据实际需求自定义。
2. Vue SSR
Vue 是另一个流行的 JavaScript 框架,也可以用于服务器端渲染。Vue 提供了 vue-server-renderer 包,通过它可以实现 Vue SSR。以下是一个 Vue SSR 的示例:
const express = require('express');
const Vue = require('vue');
const serverRenderer = require('vue-server-renderer').createRenderer();
const app = express();
app.get('/', (req, res) => {
const vm = new Vue({
template: '<div>{{ message }}</div>',
data: {
message: 'Hello, Vue SSR!'
}
});
serverRenderer.renderToString(vm, (err, html) => {
if (err) {
console.error(err);
return res.status(500).send('服务器内部错误');
}
res.send(`
<html>
<head>
<title>Vue SSR Demo</title>
</head>
<body>
<div id="app">${html}</div>
<script src="bundle.js"></script>
</body>
</html>
`);
});
});
app.listen(3000, () => {
console.log('Server is listening on port 3000');
});
这里我们通过模板和数据创建一个 Vue 实例,然后使用 vue-server-renderer 中提供的 createRenderer 方法渲染为字符串。这个过程是异步的,所以需要在回调函数中将结果返回给浏览器。
3. Angular SSR
Angular 是另一个流行的 JavaScript 框架,也可以用于服务器端渲染。Angular 提供了 @nguniversal/express-engine 包,它可以实现 Angular SSR。以下是一个 Angular SSR 的示例:
const express = require('express');
const ngExpressEngine = require('@nguniversal/express-engine').ngExpressEngine;
const { AppServerModuleNgFactory } = require('./dist/server/main');
const app = express();
app.engine('html', ngExpressEngine({
bootstrap: AppServerModuleNgFactory
}));
app.set('view engine', 'html');
app.set('views', 'dist/browser');
app.get('/', (req, res) => {
res.render('index', { req, res });
});
app.use(express.static('./dist/browser'));
app.listen(3000, () => {
console.log('Server is listening on port 3000');
});
这里我们使用 @nguniversal/express-engine 包提供的 ngExpressEngine 方法将 Angular 应用渲染为 HTML 页面,然后使用 express-engine 将其输出给浏览器。需要注意的是,这里需要将编译好的 Angular 代码放到 dist 目录中。
总结
本文介绍了三种使用 JavaScript 框架的服务器端渲染方案:React SSR、Vue SSR 和 Angular SSR。服务器端渲染可以解决单页面应用的一些问题,在性能和 SEO 上都有优势。同时,各框架也都提供了相应的工具和库,方便开发者进行服务器端渲染。