在需要首屏渲染速度优化的场景下,大家或多或少都听到过服务端同构渲染,本站也使用到了,仅以此文记录下当时查阅的资料。
首先看下web页面渲染的历史:服务端渲染 -> 客户端渲染 -> 服务端同构渲染(Server Side Render)
服务端渲染
其实早期的 Web页面渲染都是在服务端进行的,服务端渲染步骤:
- 客户端发请求
- 服务端查询数据库取数据
- 服务端将数据和模板渲染为完整 HTML
- 服务端发送给客户端
- 客户端接收直接展示
以JSP开发技术为例:
然而,在网页越来越复杂的情况下,这种方式存在很多不足:
- 前后端代码完全耦合在一起,不利于开发和维护
- 前端没有足够发挥空间(前端只单纯展示)
- 服务端压力大
- 用户体验一般(每次查看新页面要刷新,而spa不需要刷新)
客户端渲染
说到渲染方式,我们普遍使用最多的就是基于客户端渲染
的前端框架
,例如 Angular,React,Vue 等。使用它们开发 SPA 单页面应用时,具有如下优缺点:
优点
- 用户体验好
- 开发效率高
- 渲染性能好
- 可维护性好
缺点
- 首屏渲染时间长
- 不利于 SEO
同构渲染
首先什么是同构?:一套代码运行在Node服务端又运行在客户端。
服务端同构渲染 SSR (Server-Side Rendering),是指在服务端完成页面的html 拼接处理, 然后再发送给浏览器,将不具有交互能力的html结构绑定事件和状态,在客户端展示为具有完整交互能力的应用程序。
基于React、Vue等框架,客户端渲染 和 服务器端渲染 的结合,核心解决 SEO 和 首屏渲染 慢的问题。
- 在服务器端执行一次,用于实现服务器端渲染(首屏直出)
- 在客户端再执行一次,用于接管页面交互
- 拥有传统服务端渲染的优点,也有客户端渲染的优点
不过也要注意几个问题
- 同构资源的处理,拿Vue来说能在服务器端中调用的生命周期只有
beforeCreate
和created
,操作DOM、Window、Document对象或者使用三方 API 时必须保证运行不报错。 - 需要Node.js Server环境,可以外面套一层Nginx
- 需要考虑更多的缓存问题,应用代码需在双端运行解析,cpu 性能消耗更大,负载均衡和多场景缓存处理比 SPA 做更多准备。
怎么实现?
目前前端流行的三种技术栈 React, Vue 和 Angular ,已经孵化出对应的服务端渲染框架,开箱即用。
React: Next.js
Vue: Nuxt.js
Angular: Nest.js
拿本站为例,使用的是Nuxt.js,作为Node.js中间件使用Renderer处理和服务所有 SSR 和资源请求,开发环境先Builder然后再渲染,生产环境直接使用nuxt build构建好的资源进行渲染。
const { Nuxt, Builder } = require('nuxt');
module.exports = options => {
const config = require('config/nuxt.front.js'));
config.dev = options.isDev;
const nuxt = new Nuxt(config);
if (options.isDev) {
new Builder(nuxt).build();
}
const middleware = async(ctx, next) => {
// Default 404
ctx.status = options.status || 200;
ctx.req.session = await ctx.session();
await nuxt.render(ctx.req, ctx.res);
let err = null;
return next().catch(e => {
err = e;
}).then(() => {
if (err) {
return Promise.reject(err);
}
// 如果后续执行逻辑有错误,则将错误返回
return new Promise((resolve, reject) => {
return { resolve, reject };
});
});
};
return middleware;
};
具体参考:Node.js从零开发博客(一)框架搭建
还没有评论,快来抢第一吧