服务端渲染
概述
SPA 单页面应用
-
优点:
- 用户体验好;
- 开发效率高;
- 渲染性能好;
- 可维护性好;
- ...
-
缺点:
- 首屏渲染时间长;
- 不利于 SEO;
借鉴了传统的服务端渲染
客户端激活为 SPA
同构应用
-
通过服务端渲染首屏直出,解决 SPA 应用首屏渲染慢以及不利于 SEO 问题;
-
通过客户端渲染接管页面内容,用户得到更好的交互体验;
-
这种方式通常称之为现代化的服务端渲染,也叫同构渲染;
-
这种方式构建的应用称之为服务端渲染应用或者是同构应用;
什么是渲染
把数据+模板拼接到一起;
例如场景:请求后端数据接口,将数据通过模板绑定语法绑定到页面当中,最后呈现给用户,这个过程就是渲染;
本质:字符串解析替换;
传统的服务端渲染
早期的 Web 页面渲染都是在服务端进行的;
流程交互图
示例
data.json
{
"title": "传统的服务器渲染示例",
"posts": [
{
"id": 1,
"title": "数据1111111",
"content": "content111111111"
},
{
"id": 2,
"title": "数据2222222",
"content": "content222222222"
},
{
"id": 3,
"title": "数据3333333",
"content": "content333333333"
}
]
}
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>{{ title }}</title>
</head>
<body>
<ul>
{{ each posts }}
<li>{{ $value.title }}, {{ $value.content }}</li>
{{ /each }}
</ul>
</body>
</html>
index.js
const express = require('express');
const fs = require('fs');
const artTemplate = require('art-template');
const app = express();
app.get('/', (req, res) => {
// 1. 获取页面模板;
const template = fs.readFileSync('./index.html', 'utf-8');
// 2. 获取数据;
const data = JSON.parse(fs.readFileSync('./data.json', 'utf-8'));
// 3. 渲染:数据 + 模板 = 最终结果;
const html = artTemplate.render(template, data);
// 4. 把渲染结果发送给客户端;
res.send(html);
});
app.listen(3000, () => console.log('running...'));
缺点
- 前后端代码完全耦合在一起,不利于开发和维护;
- 前端没有足够发挥空间;
- 服务端压力大;
- 用户体验一般;
客户端渲染
流程交互图
- 【后端】负责处理数据接口;
- 【前端】负责将接口数据渲染到页面中;
优点
- 【前端】更加独立,不再受限于【后端】
不足
- 首屏渲染慢;
- 不利于 SEO;
为什么客户端渲染首屏渲染慢
客户端渲染会先向服务端请求一个空白页面,然后加载页面中的脚本,再根据脚本中的ajax 请求向服务器获取数据,根据获取到的数据进行动态渲染。相较于服务端渲染,此过程中的过多请求造成了服务端首屏渲染慢的现象。
为什么客户端渲染不利于 SEO
搜索引擎通过抓取页面的内容然后呈现给用户,而客户端渲染被抓取到的页面只是一个空白的页面,没有实际内容,因此搜索引擎无法从中获取有效信息,因此服务端渲染不利于 SEO。
现代化的服务端渲染(同构渲染)
同构渲染 = 后端渲染 + 前端渲染
-
基于 React、Vue 等前端框架,客户端渲染和服务器渲染的结合
- 在服务器端执行一次,用于实现服务器端渲染(首屏直出);
- 在客户端再执行一次,用于接管页面交互;
-
核心解决 SEO 和首屏渲染慢的问题;
-
拥有传统服务端渲染的优点,也有客户端渲染的优点;
流程交互图
如何实现同构渲染?
-
使用 Vue、React 等框架的官方解决方案;
- 优点:有助于原理理解;
- 缺点:需要搭建环境,比较麻烦;
-
使用第三方解决方案;
- React 生态的 Next.js;
- Vue 生态的 Nuxt.js;
同构渲染应用的问题:
-
开发条件有限:
- 浏览器特定的代码只能在某些生命周期的钩子函数中使用;
- 一些外部扩展库可能需要特殊处理才能在服务端渲染应用中运行;
- 不能在服务端渲染期间操作 DOM;
- 某些代码操作需要区分运行环境;
- ...
-
涉及构建设置和部署的更多要求:
客户端渲染 同构渲染 构建 仅构建客户端应用即可 需要构建两个端 部署 可以部署在任意 Web 服务器中 只能部署在 Node.js 服务器 -
更多的服务器负载:
- 在 Node 中渲染完整的应用程序,相比仅仅提供静态文件的服务器,需要大量占用 CPU 资源;
- 如果应用在高流量环境下使用,需要准备相应的服务器负载;
- 需要更多的服务端渲染优化工作处理;
服务端渲染的使用建议:
- 首屏渲染速度是否真的重要?
- 是否真的需要 SEO ?