什么是 SSR 服务端渲染
一、服务端渲染的定义
1、什么是服务端渲染
SSR(server side render)服务端渲染就是在浏览器请求页面 URL 时,服务端将需要的 HTML 文本组装好,并返回给浏览器,这个 HTML 文本被浏览器解析后,不需要经过 JS 脚本的执行,即可直接构建出希望的 DOM 树并展示到页面中。这个服务端组装 HTML 的过程,叫做服务端渲染。
2、服务端渲染的由来
2-1、Web1.0 时代
在没有 AJAX 时,也就是 web1.0 时代,几乎所有应用都是服务端渲染,那个时候的页面渲染是浏览器请求页面 URL,然后服务器接收到请求后,到数据库查询数据,将数据丢到后端的组件模板(php、asp、jsp 等)中,并渲染成 HTML 片段,接着服务器在组装这些 HTML 片段,组成一个完整的 HTML,最后返回给浏览器,这个时候,浏览器已经拿到了一个完整的被服务器动态组装出来的 HTML 文本,然后将 HTML 渲染到页面中,过程没有任何 JS 代码的参与:
2-2、客户端渲染
在 WEB1.0 时代,服务端渲染看起来是一个当时最好的渲染方式,但随着业务的日益复杂和后续 AJAX 的出现,渐渐暴露出 WEB1.0 服务器渲染的缺点:
- 每次更新页面的一小的模块,都需要重新请求一次页面,重新查一次数据库,重新组装一次 HTML;
- 前端 JS 代码和后端(jsp、php、jsp)代码混杂在一起,使日益复杂的 WEB 应用难以维护;
随着 nodejs 的出现,前端开启了一场前后端分离的运动。前后端分离后,网页开始被当成了独立的应用程序(SPA),前端开始接管页面渲染的事,后端团队则负责提供数据查询与处理的 API:
回顾一下页面的渲染流程:
- 浏览器通过请求得到一个 HTML 文本;
- 渲染进程解析 HTML 文本,构建 DOM 树;
- 解析 HTML 的同时,如果遇到内联样式或者样式脚本,则下载并构建样式规则(style rules),若遇到 JS 脚本,则会下载执行脚本;
- DOM 树和样式规则构建完成之后,渲染进程将两者合并成渲染树(render tree)
- 渲染进程开始对渲染树进行布局,生成布局树(layout tree)
- 渲染进程对布局树进行绘制,生成绘制记录;
- 渲染进程的对布局树进行分层,分别栅格化每一层,并得到合成帧;
- 渲染进程将合成帧信息发送给GPU进程显示到页面中。
可以看到,页面的渲染其实就是浏览器将 HTML 文本转为页面帧的过程。而如今大部分 WEB 应用都是使用 JS 框架(Vue、React)进行页面渲染,也就是说,在执行 JS 脚本时,HTML 页面已经开始解析并且构建 DOM 树了,JS 脚本只是动态的改变 DOM 树的结构,使得页面成为希望成为的样子,这种渲染方式叫动态渲染,也叫客户端渲染(client side render)
2-3、服务端渲染
随着单页应用(SPA)的发展,SEO 出了问题,而且 JS 脚本也不断臃肿,使得首屏渲染比 Web1.0 时的服务端渲染还慢。于是出现了用 nodejs 在服务器进行页面的渲染,进而再次出现了服务端渲染。
大体流程与客户端渲染相似:
- 首先浏览器请求 URL,前端服务器接收到 URL 请求后,根据不同的 URL 向后端服务器请求数据;
- 请求完成后,前端服务器组装一个携带具体数据的 HTML 文本返回给浏览器;
- 浏览器得到 HTML 后开始渲染页面,同时加载并执行 JS 脚本,给页面上的元素绑定事件,让页面变得可交互;
- 当用户与浏览器进行交互时,浏览器会执行 JS 脚本向后端服务器请求数据,拿到之后再次执行 JS 代码动态渲染页面。
3、SSR 的优缺点
与客户端的单页应用 (SPA) 相比,SSR 的优点在于:
- 更好的 SEO:搜索引擎爬虫可以直接看到完全渲染的页面,有利于 SEO。
- 更快的首屏加载:服务端渲染的 HTML 无需等到所有的 JS 都下载并执行完之后才显示,所以用户将会更快地看到完整渲染的页面。除此之外,数据获取过程在首次访问时在服务端完成,相比于从客户端获取,有更快的数据库连接;
- 统一的心智模型:可以使用相同的语言以及相同的声明式、面向组件的心智模型来开发整个应用,而不需要在后端模板系统和前端框架之间来回切换;
使用 SSR 时还有一些权衡之处需要考量:
- 代码兼容性问题:为了实现服务端渲染,应用中需要兼容服务端和客户端两种运行情况,而一些外部库只能在客户端运行,需要对其进行特殊处理,才能在服务器渲染的应用程序中运行;
- 涉及构建设置和部署的更多要求:服务端渲染的应用需要处于能让 Node.js 服务器运行的环境,不像静态的 SPA 那样可以部署在任何静态文件服务器上;
- 更高的服务端负载:在 Node.js 中渲染一个完整的应用会占用 CPU 资源,因此预期有高流量,需要为相应的服务器负载做好准备,并采用合理的缓存策略。
因此在使用 SSR 服务端渲染之前,开发者需要考虑投入产出比,比如大部分应用系统都不需要 SEO,而且首屏时间并没有非常的慢,如果使用 SSR 反而小题大做。
4、SSR vs SSG
SSG(Static-Site Generation)静态站点生成即预渲染,是另一种流行的构建快速网站的技术。如果用服务端渲染一个页面所需的数据对每个用户来说都是相同的,那么可以只渲染一次,提前在构建过程中完成,而不是每次请求进来都重新渲染页面。预渲染的页面生成后作为静态 HTML 文件被服务器托管。
SSG 保留了和 SSR 应用相同的性能表现:它带来了优秀的首屏加载性能。同时,它比 SSR 应用的花销更小,也更容易部署,因为它输出的是静态 HTML 和资源文件。这里的关键词是静态:SSG 仅可以用于消费静态数据的页面,即数据在构建期间就是已知的,并且在多次部署期间不会改变。每当数据变化时,都需要重新部署。
如果只是为了优化为数不多的营销页面的 SEO (例如 /、/about 和 /contact 等)
,可以使用 SSG 而非 SSR,非常适合构建基于内容的网站,比如文档站点或者博客。
常见的静态站点生成器:
二、同构
1、同构的定义
在服务端渲染中,有两种页面渲染的方式:
- 浏览器在交互过程中,请求新的数据并动态更新渲染页面(在客户端组装 HTML)
- 前端通过请求服务器获取数据并组装 HTML 返回给浏览器,浏览器直接解析 HTML 后渲染页面(在服务端组装 HTML)
所谓同构,就是让一份代码既可以在客户端执行,也可以在服务端执行,并且执行效果一样,都是完成这个 HTML 的组装,正确显示页面。也就是说,一份代码既可以客户端渲染,也可以服务端渲染。
2、同构的条件
实现客户端与服务端的路由、模型组件、数据模型的共享: