同时使用多个
ReactDOM.render
函数对性能可能会有多糟糕?例如,最多 30+ ReactDOM.render
呼叫。
我知道这听起来可能很奇怪。我目前正在开发一个使用单个
ReactDOM.render
函数的大型网络项目。我们遇到的最大问题之一是更新到 React 18。由于该项目相当大并且包含许多遗留代码,因此在很多地方您都可以遇到最新 React 版本不支持的遗留方法的使用。我想将一个 SPA 拆分到多个独立的子应用程序(也称为微前端)上,但仍然使用单个部署构建,拥有可以在应用程序之间共享的内存缓存,为用户保留 SPA 体验等。然而,同时时间有能力在较新版本的 React 上逐步迁移。
我们已经通过重构两个子应用程序成功创建了一个可行的概念证明。目前每个应用程序的启动看起来都有点像这样:
// Subscribe on URL path change.
observer.on('changed', () => {
if (window.location.path.includes(targetPath)) {
ReactDOM.render(<App />, elementContainer);
} else {
ReactDOM.unmountComponentAtNode(elementContainer);
}
});
正如你所看到的,我们不会立即启动React,除非我们输入特定的路由。但理想情况下,我更喜欢应用程序的入口点如下所示:
const AppEntryPoint = () => {
<Switch>
<Route path="...">
<App />
</Route>
<Route>{null}</Route>
</Switch>
};
ReactDOM.render(<AppEntryPoint />, elementContainer);
问题是:初创公司拥有 30 多个这样的入口点,情况可能有多糟糕?还有其他我没有注意到的严重问题吗?
我实际上已经完成了类似的升级旧应用程序的操作,效果很好。我认为累积渲染时间与将其放在一棵树中非常相似。
但是,我认为在这样做之前你应该仔细考虑一下。发行说明说:
虽然改变通常很小,但您仍然可以按照自己的节奏进行改变。 React 18 中的新渲染行为仅在应用程序中使用新功能的部分启用。
老实说,这可能是状态更新批处理导致的少量组件损坏。你的方法不一定是正确的,这取决于情况有多糟糕;但只有在非常极端的情况下才应该这样做。这将付出巨大的代价,而且也很难扭转。也许是少数通用组件有问题?
您可以将所有状态更新包装在一起,然后向后删除它们:https://blog.devgenius.io/understand-automatic-batching-in-react-18-fb5b8fdf062d
我通常会鼓励像您这样的增量方法,但您应该仔细考虑增量与大爆炸的成本,因为与最终状态相比,增量方法所提议的更改会有多大。
我还要补充一点,如果您这样做,最好将占位符 HTML 元素添加到页面中 - 然后查询这些元素并加载 React 树。耦合到 URL 将使移动代码变得更加困难。这过去对我有用。