背景
有点背景。该系统是一个完全同构的堆栈。最高级别的App组件呈现模板,页面,dom元素和更多组件。看看react代码,我发现它渲染〜1500组件(这包括任何简单的dom标签被视为一个简单的组件,< p>这是一个反应组件< / p> ;. 在开发中,渲染〜1500个组件需要约200-300ms。通过删除一些组件,我能够得到〜1200组件渲染在〜175-225毫秒。 在生产中,〜1500组件的renderToString需要大约50-200ms。 时间似乎是线性的。没有一个组件很慢,而是许多组件的总和。 问题 这在服务器上创建一些问题。冗长的方法导致服务器响应时间长。 TTFB比它应该高得多。使用api调用和业务逻辑,响应应为250ms,但使用一个250ms的renderToString它是双倍的!不好的SEO和用户。此外,作为同步方法,renderToString()可以阻止节点服务器和备份后续请求(这可以通过使用2个单独的节点服务器来解决:1作为Web服务器,1作为一个服务单独渲染反应)。 尝试 理想情况下,renderToString在生产中需要5-50ms。我一直在努力的一些想法,但我不知道什么最好的方法是。 想法1:缓存组件 标记为“静态”的任何组件都可以缓存。通过保持带有渲染标记的缓存,renderToString()可以在渲染之前检查缓存。如果它找到一个组件,它会自动抓取该字符串。在高级组件执行此操作将保存所有嵌套的子组件的安装。您必须将缓存的组件标记的反应rootID替换为当前的rootID。 想法2:将组件标记为简单/愚钝 通过将组件定义为“简单”,反应应该能够在渲染时跳过所有生命周期方法。 React已经针对核心反应dom组件(< p />,< h1 />等)做到了这一点。将很好扩展自定义组件以使用相同的优化。
想法3:在服务器端渲染上跳过组件
不需要由服务器返回的组件(没有SEO值)可以在服务器上简单地跳过。一旦客户端加载,设置一个clientLoaded标志为true,并将其传递下来强制重新渲染。
关闭和其他尝试
到目前为止,我实现的唯一解决方案是减少在服务器上呈现的组件数量。
我们正在寻找的一些项目包括:
> React-dom-stream https://github.com/aickin/react-dom-stream(仍在为测试实现这一点)
> Babel内联元素https://babeljs.io/docs/plugins/transform-react-inline-elements/(似乎这是沿着想法2的线)
有人面临类似的问题吗?你能做什么?
谢谢。
RoutingContext将为react-router路由中的每个模板调用createElement。这允许你注射任何你想要的道具。我们还使用助焊剂。我们发送一个大对象的序列化版本。在我们的例子中,我们在createElement中做flux.serialize()。串行化方法可能需要〜20ms。有4个模板,这将是额外的80ms到你的renderToString()方法!
旧代码:
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,serializedFlux: serializedFlux }); return <Component {...props} />; } var start = Date.now(); markup = renderToString(<RoutingContext {...renderProps} createElement={createElement} />); console.log(Date.now() - start);
在我的情况下,这有助于减少renderToString()时间从〜120ms到〜30ms。 (你仍然需要添加1x serialize()的〜20ms的总数,这发生在renderToString()之前)这是一个很好的快速改进。 – 重要的是要记住要始终正确地做事情,即使你不知道立即的影响!