- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我注意到reactDOM.renderToString()
在服务器上渲染大型组件树时,方法开始显着减慢。
一些背景知识。该系统是一个完全同构的堆栈。最高级别App
组件渲染模板、页面、dom 元素和更多组件。查看 React 代码,我发现它渲染了约 1500 个组件(这包括任何被视为简单组件的简单 dom 标记, <p>this is a react component</p>
。
在开发过程中,渲染约 1500 个组件需要约 200-300 毫秒。通过删除一些组件,我能够在大约 175-225 毫秒内渲染大约 1200 个组件。
在生产中,大约 1500 个组件上的 renderToString 大约需要大约 50-200 毫秒。
时间看起来确实是线性的。没有一个组件是慢的,而是许多组件的总和。
这会给服务器带来一些问题。冗长的方法会导致服务器响应时间较长。 TTFB 比应有的要高很多。对于 api 调用和业务逻辑,响应时间应该是 250 毫秒,但是对于 250 毫秒的 renderToString,响应时间增加了一倍!对 SEO 和用户不利。此外,作为同步方法,renderToString()
可以阻塞节点服务器并备份后续请求(这可以通过使用 2 个独立的节点服务器来解决:1 个作为 Web 服务器,1 个作为单独渲染 React 的服务)。
理想情况下,在生产环境中 renderToString 需要 5-50 毫秒。我一直在研究一些想法,但我不确定最好的方法是什么。
任何标记为“静态”的组件都可以被缓存。通过使用渲染的标记保留缓存,renderToString()
可以在渲染之前检查缓存。如果它找到一个组件,它会自动抓取该字符串。在高级组件上执行此操作将保存所有嵌套子组件的安装。您必须将缓存的组件标记的react rootID 替换为当前的rootID。
通过将组件定义为“简单”,React 应该能够在渲染时跳过所有生命周期方法。 React 已经为核心 React dom 组件( <p/>
、 <h1/>
等)做到了这一点。扩展自定义组件以使用相同的优化会很好。
服务器不需要返回的组件(没有 SEO 值(value))可以简单地在服务器上跳过。客户端加载后,设置 clientLoaded
标记为true
并将其传递下来以强制重新渲染。
到目前为止,我实现的唯一解决方案是减少服务器上呈现的组件数量。
我们正在考虑的一些项目包括:
有人遇到过类似的问题吗?你能做什么?谢谢。
最佳答案
使用react-router1.0和react0.14,我们多次错误地序列化了我们的flux对象。
RoutingContext
将为你的react-router路由中的每个模板调用createElement
。这允许您注入(inject)任何您想要的 Prop 。我们也使用助焊剂。我们发送一个大对象的序列化版本。在我们的例子中,我们在 createElement 中执行 Flux.serialize() 操作。序列化方法可能需要大约 20 毫秒。如果有 4 个模板,您的 renderToString()
方法将额外花费 80 毫秒!
旧代码:
function createElement(Component, props) {
props = _.extend(props, {
flux: flux,
path: path,
serializedFlux: flux.serialize();
});
return <Component {...props} />;
}
var start = Date.now();
markup = renderToString(<RoutingContext {...renderProps} createElement={createElement} />);
console.log(Date.now() - start);
很容易对此进行优化:
var serializedFlux = flux.serialize(); // serialize one time only!
function createElement(Component, props) {
props = _.extend(props, {
flux: flux,
path: path,
serializedFlux: serializedFlux
});
return <Component {...props} />;
}
var start = Date.now();
markup = renderToString(<RoutingContext {...renderProps} createElement={createElement} />);
console.log(Date.now() - start);
就我而言,这有助于将 renderToString()
时间从约 120 毫秒减少到约 30 毫秒。 (您仍然需要将 1x serialize()
的大约 20ms 添加到总数中,这发生在 renderToString()
之前)这是一个很好的快速改进。 -- 重要的是要记住始终正确地做事,即使您不知道立即的影响!
关于performance - React renderToString() 性能和缓存 React 组件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34728962/
我知道它只是将 HTML 呈现为文本,所以说到类组件,只有 contructor()和 render()在 renderToString() 期间调用方法.但是我注意到了一些关于函数组件的奇怪行为。考
我在服务器上渲染 react 组件,当转到路由时收到错误消息: const renderToString = ReactDOMServer.renderToString const fac =
如果我这样做 const clicked = () => console.log(“click”); renderToString(Click here 当我打印出呈现的字符串时,我只看到 Click
我为react16创建了新的样板。 https://github.com/jasonvillalon/react16-boilerplate 它在开发中运行时可以使用: npm start npm s
我有一个脚本,它读取reactjs文件,然后使用renderToString将其渲染为html。但是 renderToString 使我的组件 className 和所有其他 pascalCased
为什么问这个问题? 我正在学习有关 js 性能和 Web 渲染的知识。 This post非常有用。 如果您点击一些链接,您将登陆 here并阅读以下内容: User code in Node.js
我一直在思考如何优化 React 服务器端渲染,尤其是我应用程序中的瓶颈部分,即同步 renterToString 调用。因为这是一个阻塞调用,所以长函数 renderToString 调用会导致我的
在 React 中,有 renderToString 和 renderToStaticMarkup。 据我所知,renderToString 保留了所有的react-id 属性,这使得加载速度变慢。那
我注意到reactDOM.renderToString()在服务器上渲染大型组件树时,方法开始显着减慢。 背景 一些背景知识。该系统是一个完全同构的堆栈。最高级别App组件渲染模板、页面、dom 元素
在 WebWorker 中,我使用 ReactDOMServer.renderToString 然后我将该字符串传递回主 UI 线程: lines = lines.map(function(l
我正在寻找与 react-dom/server.renderToString 等效的 Angular 2 import { renderToString } from 'react-dom/serve
我正在尝试复制这个 fiddle : http://jsfiddle.net/jhudson8/135oo6f8/ (我也试过这个例子 http://codepen.io/adamaoc/pen/wB
我有一个应用程序,其中 webpack 配置为模块 bundler ,babel 作为我的 js 编译器。全部都在 Node 引擎上。我设置当我运行 npm run dev 时,将会发生以下流程: w
我正在为我的 React/Express 应用程序设置服务器端渲染,但遇到与调用 react-dom/server 相关的语法错误。 renderToString()方法。我正在大致遵循本教程 - h
我正在尝试使用 React 和 React-router 进行服务器端渲染。到目前为止,它只是来自各种来源的复制粘贴代码。但是当我尝试使用 Node 运行应用程序时出现语法错误(不是运行时错误)。下面
我正在尝试使用 Webpack 设置同构服务器端渲染 React 应用程序,但是当我尝试使用 renderToString 将我的 React 代码转换为字符串时出现此错误: Warning: Rea
我正在使用 React v.16.12.0 和 @MaterialUI/core v4.8.1。 我正在尝试为 React Leaflet Marker 创建自定义图标。图标是 Fab Materia
我有一个常规的 React 应用程序 (CRA)。在应用程序的一部分中,我使用 Mapbox 来显示 map ,并且要呈现弹出窗口,我需要传入要呈现的 html 内容字符串。我仍然想使用 React
React 有一个新的候选版本,v 15.0.0。由于 renderToString 方法现在在库中已被弃用,并且显然在未来版本中将不再使用,那么在新版本中如何支持 React 的服务器端渲染呢? 在
我正在使用Leaflet开发一个应用程序(通过react-leaflet)。 Leaflet直接操作DOM。 React-leaflet 库不会改变这一点,它只是为您提供 React 组件,您可以使用
我是一名优秀的程序员,十分优秀!