同构渲染

420 阅读5分钟

同构渲染

​ 在开始Vue服务端渲染之前,我们必须要了解,现在主流的渲染方式,因为主流的渲染方式不能满足,或者说不能完美的解决某些问题,才会诞生一种新的解决方案。我个人在学习任何一门新技术之前,都会先了解现在的技术存在什么问题,也就是去了解新技术出现的原因。只有清楚前因后果,才不至于一脸茫然(避免做一个只会用技术的coder),原理才能理解透彻。废话不多说,直接开始。

客户端渲染

​ 在前后端分离后,Vue,React等框架所构建的 单页应用(SPA)具有用户体验好、渲染性能好、可维护性高等优点。但也也有一些很大的缺陷,其中 主要涉及到以下两点:

  1. 首屏加载时间过长

    传统服务端渲染直接获取服务端渲染好的 HTML ,单页应用使用 JavaScript 在客户端获取数据,然后将数据添加到 HTML中 来呈现内容,用户需要等待客户端 JS 解析执行完成才能看到页面,导致首屏加载时间变长,影响用户体验会有一定降级。

  2. 不利于 SEO 当搜索引擎爬取网站 HTML 文件时,单页应用的 HTML 没有内容,因为单页面应用需要通过客户端 JavaScript 解析执行才能生成网页内容,而目前的主流的搜索引擎对于这一部分内容的抓取还不是很好。

传统的服务端渲染

​ 传统的服务端渲染,最早的PHP,JSP等都是,后来结合模板引擎(如art-template)的服务端框架。我们可以使用node来体验一下传统的服务端渲染。

const express = require('express') 
const fs = require('fs') 
const template = require('art-template') 
const app = express()
app.get('/', (req, res) => { 
    // 1. 得到模板内容 
	const templateStr = fs.readFileSync('./index.html', 'utf-8')
	// 2. 得到数据
	const data = JSON.parse(fs.readFileSync('./data.json', 'utf-8'))
	// 3. 渲染:数据 + 模板 = 完整结果 const html = template.render(templateStr, data)
	console.log(html)
	// 4. 把渲染结果发送给客户端 
    res.send(html)
})
app.listen(3000, () => console.log('running...'))
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>Document</title>
  </head>
  <body>
    <h1>{{ message }}</h1>
    <ul>
      {{ each todos }}
      <li>{{ $value.title }}</li>
      {{ /each }}
    </ul>
  </body>
</html>

上面我们简单实现了服务端渲染的逻辑,但是服务端渲染也存在一些问题

  1. 用户体验较差,每访问一个页面,都要请求服务器,刷新页面。
  2. 页面展示的内容在服务端生成,导致服务器的压力较大。
  3. 前后端耦合在一起,影响开发效率以及开发体验

同构渲染

​ 上述我们对比了服务端渲染和客户端渲染的优缺点,发现他们其实可以通过互补对方的缺点来实现一个完美的方案。所以这时候就诞生了另一种方式,即同构渲染,也就是服务端渲染 + 客户端渲染

流程

  1. 客户端发起请求
  2. 服务端渲染首屏内容 + 生成客户端 SPA 相关资源
  3. 服务端将生成的首屏资源发送给客户端
  4. 客户端直接展示服务端渲染好的首屏内容
  5. 首屏中的 SPA 相关资源执行之后会激活客户端 Vue
  6. 之后客户端所有的交互都由客户端 SPA 处理

同构渲染时通过上述的步骤来实现同构渲染的,具体的细节我们稍后再谈。我们只看上述的步骤,发现比起来客户端渲染或者服务端渲染更加的复杂。虽然同构渲染解决首屏速度慢,有利于SEO等问题,但依旧存在很多的问题。如:

  1. 服务器端负载大。在 Node.js 中渲染完整的应用程序,显然会比仅仅提供静态文件的 server 更加大量占用 CPU 资源 (CPU-intensive - CPU 密集),因此如果你预料在高流量环境(high traffic) 下使用,请准备相应的服务器负载,并明智地采用缓存策略。
  2. 开发的成本和难度会比较大。
  3. 要处于 Node.js server 运行环境。

同构渲染框架

​ 因为直接使用Vue等框架提供的服务端渲染会比较麻烦,所以业界诞生了一些解决方案。如下:

  • React 生态中的 Next.js
  • Vue 生态中的 Nuxt.js
  • Angular 生态中的 Angular Universal
实现原理

同构渲染的原理.svg

技术选型

​ 任何一门技术使用之前,我们都应该考虑是否要选择他。因为随着应用的体积增大,我们应该尽可能的避免引入不需要的技术。

那么对于同构渲染框架来说,主要的解决问题是首屏加载时间过长和SEO利用的问题。首屏加载时间过长,如果你的应用不太care这件事(如B端应用的管理后台等),完全没必要去使用。相反如果你的应用很看重SEO,并且对用户体验有一定要求。或许同构渲染框架是一个比较好的选择。

​ 这篇笔记只是对客户端,服务端渲染的缺陷的一次概述,也对同构应用的产生原因,原理做了大致的说明。具体的细节,包括如何使用一个同构渲染框架搭建一个项目,后续会继续更新。