前端渲染、服务器端渲染、同构渲染

前端渲染、服务器端渲染、同构渲染
原创nysheng 最后发布于2019-08-22 10:42:07 阅读数 310  收藏
展开
一、引
很久前,几乎所有网站都使用 ASP、Java、PHP 这类做后端渲染,但是前几年 jQuery、Angular、React、Vue 等 JS 框架的大行其道,大家转向了前端渲染。从 2014 年起又开始流行了同构渲染,号称是未来,集成了前后端渲染的优点,但转眼间三年过去了,好像还是前端渲染的天下。同构到底是不是未来?自己的项目该如何选型?我想不应该只停留在追求热门和拘泥于固定模式上,忽略了前后端渲染之“争”的“核心点”,关注如何提升“用户体验”。

二、概念
「后端渲染」指传统的 ASP、Java 或 PHP 的渲染机制;
「前端渲染」指使用 JS 来渲染页面大部分内容,代表是现在流行的 SPA 单页面应用;
「同构渲染」指前后端共用 JS,首次渲染时使用 Node.js 来直出 HTML。一般来说同构渲染是介于前后端中的共有部分。
2.1 前端渲染的优势
局部刷新。无需每次都进行完整页面请求
懒加载。如在页面初始时只加载可视区域内的数据,滚动后 rp 加载其它数据,可以通过 react-lazyload 实现
富交互。使用 JS 实现各种酷炫效果
节约服务器成本。省电省钱,JS 支持 CDN 部署,且部署极其简单,只需要服务器支持静态文件即可
天生的关注分离设计。服务器来访问数据库提供接口,JS 只关注数据获取和展现
JS 一次学习,到处使用。可以用来开发 Web、Serve、Mobile、Desktop 类型的应用
2.2 后端渲染的优势
服务端渲染不需要先下载一堆 js 和 css 后才能看到页面(首屏性能)
有利于SEO
服务端渲染不用关心浏览器兼容性问题(随意浏览器发展,这个优点逐渐消失)
对于电量不给力的手机或平板,减少在客户端的电量消耗很重要
以上服务端优势其实只有首屏性能和 SEO 两点比较突出。但现在这两点也慢慢变得微不足道了。React 这类支持同构的框架已经能解决这个问题,尤其是 Next.js 让同构开发变得非常容易。还有静态站点的渲染,但这类应用本身复杂度低,很多前端框架已经能完全囊括。

三、各有优劣
可以达成共识的是,未来是前端渲染的天下,没人开始往服务器端渲染走。但是同构渲染还处于不确定的讨论中。

3.1 前端渲染
最大的问题就是 SEO、首屏性能。前端渲染常使用的 SPA 会把所有 JS 整体打包,导致的问题就是文件太大,等待很长时间。特别是网速差的时候。SEO 很好理解。由于传统的搜索引擎只会从 HTML 中抓取数据,一上来的空网页导致页面无法被抓取。

3.2同构渲染
性能
个性化的缓存是一个问题。可以把每个用户个性化信息缓存到浏览器,这是一个天生的分布式缓存系统。我们有个数据类应用通过在浏览器合理设置缓存,双十一当天节省了 70% 的请求量。试想如果这些缓存全部放到服务器存储,需要的存储空间和计算都是很非常大。

不容忽视的服务器端和浏览器环境差异
前端代码在编写时并没有过多的考虑后端渲染的情景,因此各种 BOM 对象和 DOM API 都是拿来即用。这从客观层面也增加了同构渲染的难度。我们主要遇到了以下几个问题:

document 等对象找不到的问题
DOM 计算报错的问题
前端渲染和服务端渲染内容不一致的问题
由于前端代码使用的 window 在 node 环境是不存在的,所以要 mock window,其中最重要的是 cookie,userAgent,location。但是由于每个用户访问时是不一样的 window,那么就意味着你得每次都更新 window。 而服务端由于 js require 的 cache 机制,造成前端代码除了具体渲染部分都只会加载一遍。这时候 window 就得不到更新了。所以要引入一个合适的更新机制,比如把读取改成每次用的时候再读取。

export const isSsr = () => (
  !(typeof window !== 'undefined' && window.document && window.document.createElement && window.setTimeout)
);

原因是很多 DOM 计算在 SSR 的时候是无法进行的,涉及到 DOM 计算的的内容不可能做到 SSR 和 CSR 完全一致,这种不一致可能会带来页面的闪动。

内存溢出
前端代码由于浏览器环境刷新一遍内存重置的天然优势,对内存溢出的风险并没有考虑充分。

异步操作
前端可以做非常复杂的请求合并和延迟处理,但为了同构,所有这些请求都在预先拿到结果才会渲染。而往往这些请求是有很多依赖条件的,很难调和。纯 React 的方式会把这些数据以埋点的方式打到页面上,前端不再发请求,但仍然再渲染一遍来比对数据。造成的结果是流程复杂,大规模使用成本高。

simple store(redux)
这个 store 是必须以字符串形式塞到前端,所以复杂类型是无法转义成字符串的,比如 function。

总的来说,同构渲染实施难度大,不够优雅,无论在前端还是服务端,都需要额外改造。

三、总结
我们赞成客户端渲染是未来的主要方向,服务端则会专注于在数据和业务处理上的优势。但由于日趋复杂的软硬件环境和用户体验更高的追求,也不能只拘泥于完全的客户端渲染。同构渲染看似美好,但以目前的发展程度来看,在大型项目中还不具有足够的应用价值,但不妨碍部分使用来优化首屏性能。做同构之前 ,一定要考虑到浏览器和服务器的环境差异,站在更高层面考虑。
————————————————
版权声明:本文为CSDN博主「nysheng」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_32867271/article/details/100009449

发布了16 篇原创文章 · 获赞 213 · 访问量 22万+

猜你喜欢

转载自blog.csdn.net/cxu123321/article/details/104222929