【问题标题】:React server side rendering performance issueReact 服务器端渲染性能问题
【发布时间】:2021-01-30 05:52:10
【问题描述】:

我正在从事一个涉及 React、Redux 和其他一些前端库的项目。我读过很多关于服务器端渲染的好东西,听起来很酷。所以我实现了服务器端渲染和客户端渲染。我在这两个之间进行了性能比较,我遇到了服务器端渲染的性能问题,不确定我做错了什么。我发现服务器端渲染需要大量 CPU/mem 资源,这大大降低了我的服务器速度。即使在一个简单的页面上,它也必须处理复杂的 react、redux 逻辑,包括存储初始化、虚拟 dom、每个请求的 css 提取。当流量很高时,情况会变得更糟,有时会停止响应。我的项目很复杂,页面有很多组件,还有很多减速器、中间件。我知道我们可以通过使用缓存来缓解这种情况,但是在我的项目中,我有数千个页面,并且内容需要根据 url 参数动态呈现并且不能过时,因此缓存不是一个可行的解决方案。即使使用缓存,如果页面命中缓存,它的渲染速度也比客户端渲染快。一旦缓存过期,服务器再次变慢。另外我觉得体验有点奇怪,因为从内容开始渲染到完成所花费的时间比客户端渲染要长得多。总体而言,客户端渲染感觉更加流畅。知道为什么吗?

【问题讨论】:

    标签: reactjs server-side-rendering


    【解决方案1】:

    纯粹用作客户端 (CSR) 库的 React 可以有效地将服务器从服务文件之外的任何事情中分担。所有的计算都发生在客户端(浏览器)上,使用它们的 CPU(解析和执行 JavaScript,渲染 React 树)和网络资源(获取 API 端点,解析响应)。请注意,即使流量增加,所有工作仍然在所有客户端之间很好地分配,服务器只需要跟上服务文件的速度。

    此外,CSR 解决方案至少还有一个可能很容易被忽视的优势。一旦执行了初始 JavaScript 包并发现了资源,浏览器仍然可以在获取网络资源(如图像)的同时解析和执行其余代码。这样,代码流和数据流是并行执行的(有点)。

    这在服务器上发生了巨大变化。要渲染组件树(ReactDOMServer.renderToString/.renderToNodeStream),您需要首先获取初始渲染所需的所有资源(引入延迟)并将它们注入应用程序的顶部。否则,React 只会渲染应用程序中不依赖任何数据的部分。渲染大型组件树是受 CPU 限制的任务。 更重要的是,注入的状态应该被序列化并与渲染的 HTML 一起传输到客户端,以便 React 可以水合。这需要通过网络向客户端发送更多数据。

    总而言之,启用 SSR 后,您的服务器比仅启用 CSR 所做的工作要多得多。

    【讨论】:

    • 感谢您的回复。根据我的经验,SSR 实际上对性能的影响更大,因为它在服务器上投入了太多的工作。在现实世界中,我无法想象需要多少台服务器来处理这种负载。渲染 React 需要的不仅仅是普通的 html。但是我仍然想知道我是否错过了任何我忽略的优化方法,因为很多人都推荐 SSR。这项技术只是实验性的还是我错过了什么