3

现有React架构无法解决的问题

 1 year ago
source link: https://www.51cto.com/article/757277.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

现有React架构无法解决的问题

作者:卡颂 2023-06-09 07:21:23
前端框架普遍遵循「单向数据流」。既然是单向数据流,那就存在跨组件传递props的情况。
978677a913646d2a6a6590b79346ed09613a23.png

大家好,我卡颂。

虽然主流前端框架都遵循:

  • 状态驱动视图
  • 单向数据流

理论上并不存在某一框架可以实现,其他框架无法实现的特性。

但是,确实存在某些框架(比如Vue、Qwik)可以,但React无法解决的问题。这就是「极致性能优化」问题。

本文来聊聊React性能优化无法解决的问题。

props下钻

前端框架普遍遵循「单向数据流」。既然是单向数据流,那就存在跨组件传递props的情况。

这种情况被称为「props下钻」(props drilling)。

比如,在下面的应用中:

  • <App/>组件定义状态number。
  • <AGrandChild/>组件消费number。
  • <BGrandChild/>组件包含改变number的方法setNumber。

这种将props(这里的number)层层向下传递(从<App/>到<AGrandChild/>)的情况,就是「props下钻」:

图片

「props下钻」是非常常见的场景。面对这种场景,React的性能怎么样呢?

props下钻的性能

思考一个问题:对于上面的例子,当调用<BGrandChild/>中的setNumber方法改变number后,哪些组件会重新render?

答案是:<App/>的所有子孙组件都会重新render。

这显然与我们的预期不符。

直觉上看,起码<B/>、<C/>及其子孙组件不应该render,毕竟他们都不依赖number。

为了达到这个目标,我们需要使用React.memo包裹<B/>、<C/>,这显然会带来额外的心智负担。

为了减少开发者的心智负担,在2021年的React Conf,黄玄带来了React Forget编译器,他能够为现有业务代码生成等效于useMemo、useCallback的代码。

也就是说,理想情况下,他能够代替开发者完成React项目的性能优化。

但是,回到我们的例子会发现 —— 即使做了性能优化,也无法达到最理想的状态。

整个应用中只有<AGrandChild/>消费了number,理想情况下,当number变化后,应该只有<AGrandChild/>需要render。

但在React中,即使性能优化后,<App/>与<AGrandChild/>沿途的组件也会render:

图片

而默认情况下(不优化性能),整个应用都会render:

图片

造成这一问题的原因在于 —— 对于任一状态,React不知道哪些组件依赖他。

在「props下钻」场景下,虽然<App/>与<AGrandChild/>沿途的组件仅仅是传递number(而不是依赖他),但React无从得知。

那如果明确的表示依赖关系,是不是能解决这个问题呢?

比如,我们不使用props,而是在<App/>定义context number,再在<AGrandChild/>中消费number:

图片

遗憾的是,在React中context的实现也是依赖组件树的遍历(可以理解为React内部实现的「props下钻」),所以并不能解决这个问题。

Signal

解决这个问题的关键在于 —— 明确状态与组件的依赖关系。

这种建立组件与状态之间依赖关系的技术叫「响应式更新」(熟悉Vue的同学应该不陌生),也有些框架称其为Signal。

应用这种技术的框架(比如Vue、Qwik),当状态变化,只有依赖该状态的组件会更新。

正是由于React底层架构的原因,导致应用的性能优化无法达到最理想的状态。

这同时也是为什么React中有很多性能优化API(比如React.memo、useMemo、 useCallback...),而采用Signal技术的框架没有这些性能优化API的原因。

责任编辑:姜华 来源: 魔术师卡颂

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK