我注意到,在服务器上呈现大型组件树时,reactDOM.renderToString()
方法开始显着减慢。
背景
一点背景知识。该系统是一个完全同构的堆栈。最高级别的App
组件呈现模板、页面、dom元素和更多组件。查看react代码,我发现它呈现了大约1500个组件(这包括任何被视为简单组件<p>this is a react component</p>
的简单dom标记。
在开发中,渲染大约1500个组件需要大约200-300ms。通过删除一些组件,我能够在175-225毫秒内获得大约1200个组件来渲染。
在生产中,大约1500个组件上的renderToString大约需要50-200ms。
时间看起来确实是线性的。没有一个组件是慢的,而是许多组件的总和。
问题
这会在服务器上产生一些问题。冗长的方法会导致服务器响应时间过长。TTFB比它应该的要高得多。对于api调用和业务逻辑,响应应该是250ms,但是对于250ms的renderToString,它是双倍的!对SEO和用户都不好。此外,作为一种同步方法,renderToString()
可以阻止节点服务器并备份后续请求(这可以通过使用两个单独的节点服务器来解决:一个作为web服务器,另一个作为单独呈现react的服务)。
尝试
理想情况下,在生产环境中使用renderToString需要5-50毫秒。我一直在研究一些想法,但我不太确定最好的方法是什么。
想法1:缓存组件
任何标记为“static”的组件都可以被缓存。通过为呈现的标记保留缓存,renderToString()
可以在呈现之前检查缓存。如果它找到一个组件,它会自动抓取字符串。在高级组件中执行此操作将节省所有嵌套子组件的挂载。您必须用当前的rootID替换缓存的组件标记的react rootID。
想法2:将组件标记为简单/愚蠢
通过将组件定义为“简单”,react应该能够在渲染时跳过所有生命周期方法。React已经为核心react dom组件(<p/>
、<h1/>
等)做了这件事。扩展自定义组件以使用相同的优化将是很好的。
想法3:跳过服务器端呈现的组件
服务器不需要返回的组件(没有SEO值)可以在服务器上简单地跳过。加载客户端后,将clientLoaded
标志设置为true
并将其向下传递以强制重新渲染。
关闭和其他尝试
到目前为止,我实现的唯一解决方案是减少在服务器上呈现的组件数量。
我们正在研究的一些项目包括:
有没有人遇到过类似的问题?你能做些什么呢?谢谢。
https://stackoverflow.com/questions/34728962
复制相似问题