写点什么

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

  • 2017-05-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-05-08 19:005068
用户头像

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

关注

评论

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

打破联接壁垒,华为云IoT到底强在哪?

华为云开发者联盟

云计算 后端 物联网 华为云 企业号九月金秋榜

中国DevOps平台市场,华为云再次位居领导者位置

华为云开发者联盟

云计算 华为云 企业号九月金秋榜

爆肝整理5000字!HTAP的关键技术有哪些?| StoneDB学术分享会#3

StoneDB

数据库 HTAP StoneDB 企业号九月金秋榜 9月月更

作为一个菜鸟前端开发,面了20+公司之后整理的面试题

beifeng1996

前端 React

前端面试哪些是必须要掌握的

loveX001

JavaScript 前端

EasyCV带你复现更好更快的自监督算法-FastConvMAE

阿里云大数据AI技术

深度学习 算法 计算机视觉

2.69分钟完成BERT训练!新发CANN 5.0加持

华为云开发者联盟

人工智能 企业号九月金秋榜

基于云原生技术打造全球融合通信网关

阿里云视频云

云原生 网络 通信 通信云

2022年面试复盘大全500道:Redis+ZK+Nginx+数据库+分布式+微服务

小小怪下士

数据库 redis 分布式 微服务 java面试

Java 面试之技术框架

小小怪下士

Java spring 编程 程序员

成为优秀程序员的8种方法

小小怪下士

Java 程序员 职业发展

Lua脚本在Redis事务中的应用实践

京东科技开发者

数据库 redis 事务 开发语言 Lua脚本

长安链ca 容器部署(解决无法访问Mysql问题)

长安链

高精度的“文件转换excel”背后藏着这些解题思路!

合合技术团队

人工智能 表格识别

这样Debug,排查问题效率大大提升...

程序知音

云图说丨DDoS防护解决方案:DDoS大流量攻击防得住

华为云开发者联盟

云计算 后端 华为云 企业号九月金秋榜

2022最新腾讯面经分享:Java 面试刷题 PDF(17 大专题 )

Java-fenn

Java 编程 程序员 面试 java面试

开发者问第四期|统一扫码服务、机器学习服务等问题解答

HarmonyOS SDK

老生常谈!数据库如何存储时间?你真的知道吗?

小小怪下士

Java 数据库 编程 程序员

数字化办公,企业OA软件技术该如何发力?

FinClip

架构师成长之路——什么是架构师

小小怪下士

Java 程序员 架构 后端

【存疑】爬虫学习中decode问题

Sher10ck

存疑

腾讯云,DevOps 领导者!

CODING DevOps

腾讯云 DevOps IDC CODING

模块一

早安

极客时间架构训练营

智能电饭煲

OpenHarmony开发者

OpenHarmony

35岁程序员自荐:我所掌握的架构技术

小小怪下士

Java 程序员 中年危机

为什么Java中有三种基础的类加载器?

小小怪下士

Java 编程 程序员 程序

英特尔Wi-Fi 7速率提升5倍,为多应用场景带来改变

科技之家

ESP32-C3入门教程 基础篇(八、NVS — 非易失性存储库的使用)

矜辰所致

ESP32-C3 9月月更 NVS

元宇宙场景技术实践|虚拟直播间搭建教程

ZEGO即构

音视频开发 元宇宙 虚拟直播

一个代码仓库(免费)与技术点 的故事

八点半的Bruce.D

GitHub Linux 网络服务 GitHub仓库

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