大家好,我是程序员鱼皮。
不知道大家有没有听说过 “服务端渲染” 这样一种技术?如今这个技术越来越流行,尤其对于以内容为核心的网站,使用服务端渲染可以大幅提升网站被搜索到的概率,所以很多企业级网站都用到了这个技术来开发,比如几个知名大站 —— B 站、C 站、G 站、P 站等等。
啥啥啥,不会有人不知道这些网站都是什么吧?
前段时间有位小伙伴专门吐槽我们开发的编程导航网站没有用服务端渲染:
看到这条评论,兄弟我有点儿难受了。说实话,我们这个网站不用服务端渲染,还不是因为。。。因为 懒 嘛!
开个玩笑,当然也有一些其他的原因。。。
服务端渲染技术虽好,但也不是万金油。2024 年,如果你还没有了解过这个技术,或者不了解它正确的应用场景,那可就真的 out 了。下面鱼皮就给大家科普下这个技术。
揭秘服务端渲染
1、什么是客户端和服务端渲染?
网站渲染可以在服务端和客户端两种环境下进行:
客户端就是你的电脑,或者具体一点,可能是你电脑上打开的浏览器;而服务端就是机房里的服务器。
在客户端渲染中,客户端会先向服务器请求 HTML 文件,服务器会返回一个基础的 HTML 文件,其中包含必要的 JavaScript 脚本。这些脚本在浏览器端运行,动态请求后端的数据、生成网页内容并渲染到页面上。
以我们的 编程导航网站 为例,就使用了客户端渲染,使用 F12 网络控制台查看加载的网站内容。可以看到刚开始加载的 HTML 文档并不包含网站的数据,只有一个标题、以及一个 JS 脚本。
这特么看起来比我刚学网站开发的时候写的记事本还简单!
接下来,浏览器会执行该脚本,并触发后续的数据请求和加载流程,逐渐显示整个页面,所以看到请求的过程是断断续续的。
与客户端渲染相对,服务端渲染是一种将网页在 服务器端 生成并渲染为 HTML 内容的技术。在这种方式下,当用户请求一个网页时,服务器会提前调用后端来获取数据并生成完整的 HTML 文档,然后将其发送到客户端(浏览器)。浏览器接收到 HTML 后,直接展示页面内容,不用再动态地向后端发送请求来获取数据。
我们的 面试刷题网站 - 面试鸭 使用的就是服务端渲染。从下图可以看到,服务端返回的 HTML 文档中,就已经有完整的网站数据和样式了:
2、二者的优缺点
由于 Ajax、Vue、React 等技术的崛起,大多数学前端的同学开发的网站都是基于客户端渲染实现的,我说的没错吧?估计大家比较熟悉的词是 SPA、SPA、SPA,天天做 SPA~
客户端渲染的优点主要是:
- 开发方便灵活:开发者不需要区分哪些数据要在服务端加载、哪些数据要在客户端加载,也不用担心哪些 API 无法在服务端使用。
- 减少服务器压力:由于渲染工作由客户端(用户自己的电脑)完成,因此服务器的负载相对较小,只需要提供静态资源。
服务端渲染的好处是:
- 减少页面初始加载时间:首次加载时展示完整内容,减少白屏时间,不用等待 JavaScript 加载和执行后才能展示内容。
- 更有利于 SEO,因为搜索引擎爬虫能够直接抓取完整页面的内容,而不依赖于 JavaScript 的执行。
这两个技术各有优缺,所以不能说服务端渲染就一定更好。总结一下二者的适用场景:如果你的网站要做 SEO、希望被更多人搜索到,首选服务端渲染,但对服务器配置的要求就更高了;如果你不需要做 SEO,比如面向企业的网站、内部网站、个人学习用的网站,或者是较为复杂、充满各种动态交互的网站,用客户端渲染就好。
能够实现服务端渲染的技术很多,以前有 Java 的 JSP、PHP 等等,现在有基于 React 的 Next.js 和基于 Vue 的 Nuxt.js 框架,可以让你直接用前端的语法开发服务端渲染项目。我们自己的网站用的就是 Next.js,开发成本已经跟客户端网站差不多了。
Next.js 还是开源的
3、静态网站生成
除了服务端渲染和客户端渲染外,还有一种常用的技术 —— 静态网站生成。
静态网站生成是一种在 构建阶段 生成静态 HTML 文件的技术。注意,是在构建时(而不是用户请求时)就已经请求后端服务器获取了数据并且把页面生成好了,用户请求的时候服务器只需要把文件发出去就行,不用再做其他处理。
搜索引擎最喜欢的就是静态 HTML 文件,可以大幅提升 SEO 效果。此外,这些静态文件还可以通过内容分发网络(CDN 缓存)进行加速,进一步减少服务器的压力。
但静态网站生成的缺点也很明显,不适合内容动态变化的网站。而且随着内容的增多,每次构建要生成大量静态页面,时间会越来越长。
基于这些优缺点,静态网站生成适合内容数量有限的、内容基本不变的网站,比如个人博客。像 VuePress、Hugo、Hexo、Astro 都是主流的静态网站生成器。
鱼皮的编程宝典就是基于 VuePress 开发的,我把制作模板也开源到了 GitHub 上:https://github.com/liyupi/codefather
当然,有问题就有解决方案。随着静态网站内容越来越多,每次构建会越来越慢,这种情况下,可以采用增量静态生成技术。允许部分页面在构建之后进行更新,而无需重新构建整个站点。这种技术适用于那些大多数内容不变、但某些部分需要动态更新的网站。
比如我改了博客里的一篇文章,那么只需要重新生成这篇文章对应的 HTML 页面即可。这样一来,可以在享受静态网站高性能、SEO 友好特性的同时,及时更新网站的内容,并减少构建时间。
不过缺点就是网站架构更复杂、维护成本更高。但值得一提的是,很多大型网站为了做 SEO 优化,专门把动态网站转为静态 HTML。
4、结合使用
实际开发中,前面讲到的几种方式可以结合使用。
比如 部分预渲染 是一种将静态页面生成与客户端渲染结合的技术。
在构建阶段或请求阶段,页面的静态部分预先渲染,比如导航栏、页脚等。页面加载时,静态部分可以直接显示。比如刚访问面试鸭刷题网站的时候看到的效果如下,这些内容无论谁访问看到的都是一样的、不变的:
然后,通过 水合 过程,客户端的 JavaScript 接管已经渲染的静态内容,并继续处理动态交互。比如请求后端获取用户登录状态、并且加载出用户的信息:
这样一来,网站兼具了服务端渲染的 SEO 友好和快速初始加载、以及客户端渲染灵活动态交互的优点。
还有一个跟部分预渲染相似的概念叫 同构渲染 ,是指同一套代码可以在服务端和客户端运行,并在服务端渲染页面的初始内容,然后在客户端接管渲染和交互。
实际情况下鱼皮也更推荐用这种方式,鱼皮带大家开发的 最新项目 中,就会使用同构渲染开发一套前端万用项目模板。