开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 22 天,点击查看活动详情
前段时间写了一篇关于 ISR 渲染概念的文章,并在团队进行了分享,得到的反馈是很多同学没有接触过服务端渲染的也没开发,不太了理解前端渲染的一些概念。因此,本篇文章从以下几个疑问入手来讲解前端渲染的基础信息:
- 渲染是什么?
- 什么是服务端渲染? (服务端渲染的运行机制)
- 什么是客户端渲染?
- 什么是同构渲染?
渲染的概念
我们可以单纯的把渲染理解为:渲染就是将页面数据和页面模版组装成html的过程
。
也就是: data + template = html
,当然data也可能什么都没有,没有数据也是一种数据。
客户端渲染(CSR)
什么是客户端渲染呢?
客户端渲染就是 data + template = html
过程在客户端进行,服务器直接转发静态 html 资源即可。
常见的形式就是:
打包的时候生成只有css、js等外链标签的空白页面,客户端在请求时,服务端不做任何处理,直接以原文件的形式返回给客户端客户端,客户端获取到页面后,在加载完js后才通过js来渲染页面内容。
优势和劣势
优势
:
- 服务器压力小,只用进行转发较小的静态页面
- 前后端分离,代码逻辑更清晰,不需要考虑代码能不能在服务端运行,不需要考虑服务端的一些注意事项。
- 可以进行局部刷新,无需每次请求完整页面、交互好可实现各种效果
劣势
:
- 不利于 SEO:网络爬虫可能看不到完整的程序源码,获取不到页面关键信息。不过现在有的搜索引擎也可以了。
- 首屏渲染慢:渲染前需要下载一堆 js 和 css 等,而且很多并不是首页需要的 js 和 css,不过按需加载也可以加快首屏加载,下载js和解析js的时间成本都不太低。
服务端渲染(SSR)
这里主要说的是传统的服务端渲染,现代的服务端渲染指的是同构渲染。
什么是服务端渲染呢?
客户端渲染就是 data + template = html
过程在服务端进行,客户端不需要渲染页面。
具体解释就是:服务端渲染的模式下,当用户第一次请求页面时,由服务器把需要的组件或页面渲染成 HTML 字符串,然后把它返回给客户端。客户端拿到手的,是可以直接渲染然后呈现给用户的 HTML 内容,不需要为了生成 DOM 内容自己再去跑一遍 JS 代码。使用服务端渲染的网站,可以说是“所见即所得”,页面上呈现的内容,我们在 html 源文件里也能找到。
优势和劣势
优势
:
- 首屏渲染快
- 利于 SEO
- 可以生成缓存片段
- 生成静态化文件
- 客户端资源更小,对用户来说更节能(对比客户端渲染的耗电)
劣势
:
- 传统服务端渲染的用户体验较差、不容易维护,通常前端改了部分 html 或者 css,后端也需要修改。
- 服务器压力大,可以用静态化来解决。
- 需要考虑服务端的一些注意事项。
客户端渲染(CSR)VS 服务端渲染(SSR)
其实前后端的渲染本质是一样的,都是字符串的拼接,将数据渲染进一些固定格式的 html 代码中形成最终的 html 展示在用户页面上。 因为字符串的拼接必然会损耗一些性能资源。
- 服务器端渲染,消耗的是 server 端的性能
- 客户端渲染,常见的手段,比如是直接生成 DOM 插入到 html 中,或者是使用一些前端的模板引擎等。他们初次渲染的原理大多是将原 html 中的数据标记(例如{{text}})替换。
为何需要使用 ssr
主要是为了亮点:
- 提升首屏加载速度
- 优化 SEO
什么是同构渲染?
何为同构?
同构是指写一份代码但可同时在浏览器和服务器中运行的应用。为了同时拥有 ssr 和 csr 的特点,当前流行的方案就是 ssr + csr 同构,比如现在比较流行的的 Next.js。
而同构渲染也就是指:在服务端先进行渲染一次(SSR,组装页面html内容),客户端拿到代码后,再进行渲染一次(CSH(client-side hydration),也就是 hydrate,主要对 html 进行事件绑定和内容校验,如果 hydrate 发现内容不一致的话,会在开发环境提示警告),后续页面的所有操作和渲染行为都和 CSR 一致(didMount后的更新页面内容都属于正常的CSR了)。
认识同构
同构应用运行原理的核心在于虚拟 DOM,虚拟 DOM 的优点在于:
- 因为操作 DOM 树是高耗时的操作,尽量减少 DOM 树操作能优化网页性能。而 DOM Diff 算法能找出 2 个不同 Object 的最小差异,得出最小 DOM 操作;
- 虚拟 DOM 的在渲染的时候不仅仅可以通过操作 DOM 树来表示结果,也能有其他的表示方法。例如虚拟 DOM 渲染成字符串(服务器渲染)等。
构建同构应用的最终目的是从一份项目源码中构建出 2 份 JavaScript 代码。一份用于在 node 环境中运行渲染出 HTML。其中用于在 node 环境中运行的 JavaScript 代码需要注意:
- 不能包含浏览器环境提供的 API;
- 不建议包含 css 代码,因为服务端渲染的目的是渲染 html 内容, 渲染出 css 代码会增加额外的计算量,影响服务端渲染,因此建议 css 需要用外联方式;
- 不能像用于浏览器环境的输出代码那样把 node_modules 里的第三方模块和 nodejs 原生模块打包进去,而是需要分开进行打包,客户端打包一份和服务端打包一份,或者打包的时候区分各自运行的文件。
扩展渲染模式
上面说的渲染模式属于基础渲染模式,现在还有了更多的渲染模式,且运用都很广泛。
- 静态化渲染:打包的时候进行
data + template = html
过程,然后客户端在请求时,服务端不做任何处理,直接以原文件的形式返回给客户端,客户端获取到也没可以正常显示页面后再去执行js内容。 - 增量静态渲染:之前有一篇文章专门介绍了 ISR 渲染模式,可以去看一下。
总结
本篇文章属于很久之前写过,但一直没有发出来过,因为日根时间原因,本次进行检查更新部分内容,如果有问题欢迎提出。
创作不易,欢迎大家➕关注➕点赞➕收藏,有问题欢迎评论区提出。
开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 22 天,点击查看活动详情