传统的服务端渲染
早期的web页面渲染都是在服务端进行的
一个简单的例子,node端读取一个页面的html并嵌入数据,最后将页面返回给前端
const express = require('express')
const fs = require('fs')
const template = require('art-template')
const app = express()
app.get('/', (req, res) => {
// 1、获取页面模板
const tpl = fs.readFileSync('./index.html', 'utf-8')
// 2、获取数据
const data = JSON.parse(fs.readFileSync('./data.json', 'utf-8'))
// 3、执行渲染
const html = template.render(tpl, data)
// 4、把渲染完的页面发送给客户端
res.send(html)
})
app.listen(3000, () => console.log('running...'))
最终页面展示的是data.json中的数据,前端请求的接口返回的数据就是已经处理好的html代码,如股应用不复杂的情况下,这种方式是完全可取的
但是如果在复杂情况下,这种方式会存在很多不足:
- 前端端代码完全耦合在一起,不利于开发和维护
- 前端没有足够的发挥空间
- 服务端压力比较大
- 用户体验一般,跳转其他页面需要重新刷新
客户端渲染
Ajax的出现使得客户端动态获取数据成为可能。
原本在服务端的工作转移到了客户端。此时后端负责处理数据接口,前端负责将数据渲染到页面中,更为独立,不再受限制于后端
但这样也存在一些明显的不足:
- 首屏渲染慢
- 不利于SEO
为什么客户端渲染首屏渲染时间长?
以Vue SPA项目为例,加载一个页面首先要请求静态页面,其次请求页面中的js脚本,最后如果有ajax的话执行ajax,这三部分并不是同时进行的,但是服务端渲染只进行一次请求,直接拿到已经编译好的html静态内容,所以首屏渲染时服务端渲染会比客户端快。
为什么客户端渲染不利于SEO?
搜索引擎请求各个网址,拿到返回的静态html字符串,根据字符串的内容进行分析、收录、排名等操作。如果是服务端渲染(SSR),搜索引擎拿到的是已经插入数据之后的html字符串,即所见即所得,有利于网站的排名,但是客户端渲染(CSR)的页面,以Vue SPA项目为例,搜索引擎拿到的就只是一个带有<div id="app"></div>的html字符串,并不会加载其中的静态资源,内容是空的,SEO自然无从谈起。
现在化的服务端渲染(同构渲染)
同构渲染=后端渲染+前端渲染
基本流程:
- 基于React、Vue等框架,客户端渲染和服务器端渲染的结合
- 在服务端执行一次,用于实现服务端渲染(首屏直出)
- 在客户端再执行一次,用于接管页面交互
- 核心在于解决SEO和首屏渲染慢的问题
- 拥有传统服务端渲染的优点,也有客户端渲染的优点 如何实现:
- 使用Vue、React等框架的官方解决方案
- 优点:有助于理解原理
- 缺点:需要搭建环境,比较麻烦
- 使用第三方解决方案
- React生态的Next.js
- Vue生态的Nuxt.js
- ...
同构渲染应用的问题
- 开发条件有限
- 浏览器中特定的代码只能在某些生命周期钩子函数中使用
- 一些外部扩展库可能需要特殊处理才能在服务端渲染应用中运行
- 不能在服务端渲染期间操作DOM
- 某些代码操作需要区分运行环境
- 涉及构建和部署的要求会更多,同构渲染应用只能部署在Node.js Server
- 更多的服务端渲染优化工作处理,如果流量比较高,需要做服务器负载的一些工作
服务端渲染的建议
- 首屏渲染速度是否真的重要
- 是否真的需要SEO