由于项目体量有限, 工作中暂时还没有遇到过需要使用 SSR 作为解决方案的项目。一直有关注,也阅读过这个技术的文档,但是一直没有仔细的尝试过,最近找到机会按照官方的 Vue SSR 指南, 试着去重头搭建了一个 Vue SSR 的 demo 站,和大家分享一下我的理解。
尤大的文档写得一向是深入浅出, 循序渐进, 很容易读懂。但是 Vue SSR 指南 却是个例外,不知道是什么原因顺序上很跳跃,不是渐进式的娓娓道来,个人感觉很难读明白。
本文对应的 SSR demo 项目仓库为: https://github.com/njleonzhang/play-vue-ssr
SPA 的问题
在使用 SPA 技术之前,我们访问的网页的主要内容都是在后台渲染好/组装好的,也就是说 HTML 里的信息很完整。
比如,我们的这个网站是后台渲染的。通过浏览器看一下他的源码(即后台给浏览器返回的内容), 我们可以发现页面里的内容存在于这个 html 里。那么对于 SPA 网站呢,看一下我们这个基于 vue 的站,浏览器里源码是啥。。。
non-SPA 源码:
SPA 源码:
不管你在浏览器上输入哪个子页面的地址,SPA 网站返回的都是这么个东西。原因嘛,那就是 SPA 的页面内容都是由 js
代码导航和渲染的,对于SPA 来说,你告诉我的地址,我最后告诉了 js,js 选择内容来渲染页面。
那么这有什么问题?有问题么? 没有么?要说有,那么主要有2方面的问题:
-
SEO.
即搜索引擎优化。WTF? 有的同学可能会问怎么说着说着扯上搜索引擎了?没错就是下面这位尼克扬同学问的。 按我的理解事情是这样的,我们做出来的商业网站很多情况下希望搜索引擎能够搜索到的,比如你们公司的官网,宣传网站,网店的页面等。你的老板肯定想让你的网站能够在百度爸爸里按照你页面上出现的内容被搜索到吧。而搜索引擎又是如何来建立索引的呢?搜索引擎会通过蜘蛛发 http get 请求的方式去访问你的网页,并根据网站的内容来建立索引。蜘蛛是不会用 js 来渲染页面然后再爬里面的内容的,它们通常就是爬一个 html 文件。那对于 SPA 页面一切就都全完了。因为每次蜘蛛来爬都是一个啥也没有的空壳子。你告诉你老板说我们的网站百度爸爸不会收录,收录的话也是个空壳子,你老板可能也会发上面这个尼克扬的图片给你,然后让你滚蛋。😂
-
首屏出现慢的问题.
非 SPA 页面后台渲染好了直接返回 HTML 给浏览器,浏览器直接展示页面。而 SPA 页面后台给浏览器返回一堆 js,前台再执行 js 去渲染页面,这能不慢么。当然慢啦,尤其是在性能比较差的客户设备上。
这2个问题么是问题么?是否一定要用 SSR 去解决?
不一定! 可能大多数的时候,并不需要。
-
SEO 问题
首先也不是所有的页面都需要 SEO,比如我们这个 SaaS 平台,天生也不需要什么 SEO,蜘蛛和你们一样没账号,页面都看不见,做个锤子的 SEO. 其次,需要 SEO 的网站也不一定要做成 SPA, 比如我们需要 SEO 的这个这个官网,页面没有太多的复杂 dom 操作,直接上 jQuery 撸就好了,关键 jQuery 还是能兼容老版本的浏览器 😂 (万恶的产品经理)。 再次,就算一定要用 SPA 同时需要 SEO,很多情况下预渲染就够用了.
这年头在天朝的互联网行业,SEO 似乎是越来越没卵用了,花钱买流量的 SMO 才是王道。拼多多,拼多多,拼得多,省(keng)得多. 瞧,公司上市了吧。(当然说 SMO 是花钱买流量是狭义的理解)
-
首屏出现慢
做个加载的菊花页面?不行么?你们公司真的已经开始在乎这几秒甚至零点秒了么?如果真的在乎,你可能确实需要 SSR.
SSR 从原理上是如何解决这2个问题的?
思路还是很好理解的,SPA 的问题归根到底不就是后台没有返回渲染好的页面,只给前台返回一个空壳子么。那如果我在你访问页面的时候,后台给你渲染返回一个正常的 HTML
不就好了么。也就说现在不给你返回简单的空壳子了,而是根据你访问的链接给你渲染一个真的 HTML 页面,然后给你返回这个真的(完整的) HTML 文件作为壳子。
尤大的图说的就是这个道理:
我们把源码编译成2份(Server bundle 和 Client bundle).
- Server bundle 运行在后台 Node 服务器上。这个 Node 服务器负责在后台渲染(Server Side Render,SSR)上面说的真的(完整的),然后返回给浏览器。这个壳子里必然有一个
<script src="client bundle">
的加载语句。 - client bundle 被浏览器通过壳子 HTML 的加载语句载入浏览器环境,并通过和壳子 HTML 的 Hydrate 后,掌管页面。
所谓
hydrate
,意译是与水化合
. client bundle 的 js 要接管页面,但是也面临着很多问题,比如页面已经渲染好了,js 肯定不应该再渲染一次了。那么不渲染的话,就需要把自己的虚拟dom
和 后台返回的这个现成的 dom 做一个绑定。这些过程是很复杂的。SSR 这个技术文档里称这个过程为 hydrate. 可以看到,除了用户首次从浏览器里访问网站会经历这个 SSR 的过程外,后续对页面的操作(翻页,点击,数据加载等),都和普通的 SPA 基本无异。
听起来 SSR 挺完美,为啥前面还说不一定要用?
恩,方案挺完美,但是也很复杂.
- 开发复杂了,因为你的代码要同时跑在浏览器和 Node 里;
- 部署复杂了,君不见多了个 Node 服务器么;
- 服务器压力也大了,和 SPA 比,本来渲染在前台,现在后台要渲染了,意味着你可能需要考虑使用页面的缓存等技术了;
你的项目真的需要 SSR,而且你也真的准备好了么?反正我们的项目不需要,我也没有准备好. 😂
总结
美丽的东西往往是有毒的, SSR
看着很美丽, 但是真正用起来还是挺困难的。本来想一篇把 Vue SSR 的 demo 搭建过程写完的,没想到只能开个头,先挖个坑吧。
系列文章: