7月QCon广州站2022,关注Web 3.0、数据架构选型、数字化转型等热门话题,点击了解 了解详情
写点什么

聊一聊服务端渲染和客户端渲染

  • 2017 年 5 月 08 日
  • 本文字数:1846 字

    阅读完需:约 6 分钟

我们在 walmart.com 网站上的大多数页面采用服务器端渲染(简称 SSR)方式。之所以选择服务器端渲染,主要出于以下两点考虑:

  • 能够为客户提供更理想的性能

  • 提供更为一致的 SEO 表现

正是由于 SSR 拥有上述优势,因此我们在将自有堆栈转换为 React 与 Node.js 时,投入了大量时间与精力以优化 SSR 性能。其中的一项关键性指标正在于页面内“明显位置”的渲染性能。我们发布的开源项目 Electrode 框架当中包含多种模块,能够有效提升 SSR 性能。感兴趣的朋友可以点击此处参阅我之前发布的各模块助益评述。

在发布Electrode 框架并强调其面向SSR 的设计思路之后,我收到了大量关于SSR 优势的疑问与评论。在今天的博文中,我将专门探讨使用SSR 在性能层面带来的改善效果——另外亦感谢 Andrew Farmer Patrick Hund 在 SEO 优势评述方面提供的协助。

理论性能收益

首先我们将通过下面这份简单的时间线图展示 SSR 与 CSR(即客户端渲染)之间的区别。

可以看到其中最大的区别在于,在使用 SSR 的情况下您的服务器对浏览器的响应结果属于已做好准备并可进行渲染的页面 HTML,而 CSR 的浏览器响应结果则属于链接至您 javascript 的空文档。这意味着您的浏览器将立足服务器进行 HTML 渲染,而无需等待全部 JavaSciprt 代码的下载与执行。在这两种情况下,我们都需要下载 React 并利用同样的流程构建一个虚拟 dom,而后附加各事件以实现页面交互——但在 SSR 方面,用户可在执行上述流程的同时查看到页面内容。而在 CSR 方面,大家则需要等待上述流程全部执行完成,而后方可进行查看。

现在,我们来了解以下注意事项:

  • 尽管在 SSR 方面,页面会提前进行渲染以帮助客户更早查看页面内容,但在 React 真正执行完成之后,查看到的内容并无法进行交互。如果客户在此期间点击某按钮,该操作亦需要等待 React 执行完成后方可起效 ;

  • SSR TTFB(即第一字节时间)速度比 CSR 更慢,因为您的服务器需要耗费时间为页面创建 HTML,而非直接发送相对较空的响应内容 ;

  • SSR 的服务器数据吞吐量要远低于 CSR 数据通量。以 React 为例,这种数据吞吐量的差异将造成显著区别。ReactDOMServer.renderToString 为一项同步 CPU 绑定调用,其中包含该事件循环,意味着服务器将无法在 ReactDOMServer.renderToString 完成之前处理其它请求。这里我们假定您的页面需要 500 毫秒进行 SSR,则意味着您每秒至多只能执行 2 项请求。请千万重视这一情况

实际用例

在下图当中,我们就 walmart.com 网站上的各生产应用对 SSR 与 CSR 进行渲染效果比对。

我们将三款应用(即主页、分类与搜索)分别立足 SSR 与 CSR 方式进行比较。相关结果来自 Chrome 浏览器所捕捉到的页面渲染时间指标。大家可能已经注意到,SSR 渲染速度要更快一些,而使用 CSR 则意味着加载过程中浏览器内将显示空白页面。大多数使用 CSR 的应用都会利用加载图标来取代这种难看的空白页面,但由于我们在正常操作中默认使用 SSR,因此在 CSR 测试中页面仍保持未经发动的空白样式。需要注意的是,上述结果皆为我们的设备在一天中特定时段内配合实际生产配置捕捉到的结果,因此经过定制化调整的方案也许在性能上有所区别——不过总体而言,其仍然足以反映一般性趋势。

上图为主页、分类与搜索页面的首次服务器响应对比。在这里我忽略掉了绿色指标条,因为其更多反映的是网络图中的其它元素。这里最值得关注的其实是文档大小与 TTFB。由于服务器会利用 HTML 对页面进行响应,因此大家可以看到 SSR 的文档总是相对较大。另外需要强调的是,正如前文中所提到,CSR 响应速度更快(除了主页,这是因为受到本次测试中某些因素的影响)。

这里再次向大家强调,上述测量指标会随着应用类型、延迟、服务器、位置以及多种其它变量的变化而有所浮动,因此请不要将其视为科学的客观事实——而仅用于反映一种普遍规律。

Electrode 框架

在我们对 SSR 与 CSR 进行 A/B 测试时,得出了以上总体趋势,而我们的数字也显示尽早进行渲染往往能够带来更理想的操作体验。

考虑到这些理由,我们的开源应用平台 Electrode 高度关注 SSR。其默认启用 SSR,而我们亦构建起多种模块以进一步提升 SSR 性能表现。感兴趣的朋友亦可点击此处参阅另一篇文章,我在其中展示了如何利用其中两款模块将RenderToString() 时间缩短达70%。

这里再次感谢Mayakumar 与Caoyang 协助我审查并调整了本篇博文的具体内容。


感谢薛命灯对本文的审校。

给InfoQ 中文站投稿或者参与内容翻译工作,请邮件至 editors@cn.infoq.com 。也欢迎大家通过新浪微博( @InfoQ @丁晓昀),微信(微信号: InfoQChina )关注我们。

2017 年 5 月 08 日 19:004396
用户头像

发布了 24 篇内容, 共 77455 次阅读, 收获喜欢 7 次。

关注

评论

发布
暂无评论
发现更多内容

小伙伴想写个 IDEA 插件么?这些 API 了解一下!

程序员小航

IDEA idea插件 教程 API IntelliJ IDEA

Scrum Master是否需要懂技术

Bob Jiang

敏捷 敏捷开发 敏捷教练 ScrumMaster

Python 多进程之间共享变量

AlwaysBeta

Python 进程

第九章作业

武鹏

LeetCode题解:70. 爬楼梯,递归+哈希表,JavaScript,详细注释

Lee Chen

大前端 LeetCode

RRedis系列(八):缓存到底该如何做到高可用?

z小赵

redis 分布式系统 高并发系统设计

格一格你的情欲念

王进行

架构师训练营第九周学习总结

张明森

金融行业区块链技术应用有了“安全符”

CECBC

谈谈敏捷中的那些模式

Bob Jiang

敏捷 敏捷开发 敏捷教练

你该知道的Docker-compose

北漂码农有话说

“PlusToken”跨国网络传销案告破,涉案400亿元!

CECBC

架构师训练营第九周作业

张明森

Dockerfile你值得拥有

北漂码农有话说

Docker

极客时间 - 架构师培训 - 9 期作业

Damon

JVM详解之:类的加载链接和初始化

程序那些事

Java JVM GC 加载

稳定匹配:幸福不靠等,脱单要主动

KAMI

生活 算法 方法论

nginx配置文件

张明森

F5G+X:给5G一个伙伴,给千行百业一个拥抱

脑极体

JVM参数手册

Rayjun

JVM GC

今天你内卷了吗?

池建强

个人成长 内卷化

微碳系:我心中的宇宙

Geek_116789

敏捷教练和Scrum Master - 敏捷转型中的两个重要角色的对比

Bob Jiang

Scrum 敏捷教练 ScrumMaster

30岁的二三事

大唐小生

总结 个人感悟

什么是算法的大O表示法

码农神说

算法 时间复杂度 Java算法 大O

搭乘政策红利“快车” 欧科云链助力区块链人才培养

CECBC

基于 opentracing + Jaeger 实现全链路追踪 ----理论部分

是老郭啊

全链路监控 OpenTracing Jaeger Go 语言

刘华:事实证明,假敏捷都比瀑布优秀

刘华Kenneth

DevOps 敏捷 软件开发

无意中参加了infoQ的一期活动,获得了所有奖项,哈哈哈。。。

诸葛小猿

InfoQ 奖品

Docker 网络

北漂码农有话说

Docker

来了来了!Docker安装及运行原理

程序员的时光

Java Docker 微服务

聊一聊服务端渲染和客户端渲染_语言 & 开发_Alex Grigoryan_InfoQ精选文章