V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
Chuckle
V2EX  ›  React

React 多人开发怎么确保性能,有没有最佳实践

  •  1
     
  •   Chuckle ·
    qxchuckle · 2025 年 7 月 9 日 · 5757 次点击
    这是一个创建于 190 天前的主题,其中的信息可能已经有所发展或是发生改变。
    一个小业务组件,随着需求迭代,越来越大,塞复杂表格、表单等等,上千行都有,导致状态一变连锁反应全都变,就算拆模块,也得 momo 、usecallback 啥的套,很容易又打破,也很麻烦。
    像 data-grid 的案例都推荐用上下文去传数据了,避免小变化导致整个表格列重渲,但是在业务里用上下文多了,感觉更难维护数据流。

    reference
    38 条回复    2025-10-23 16:19:44 +08:00
    Chuckle
        1
    Chuckle  
    OP
       2025 年 7 月 9 日
    数据都从接口的来的,而且很大,不可避免的就是用上 useDeepCompareEffect ,在可编辑虚拟表格等场景下,能明显感觉卡顿,React scan 浏览器插件、f12 性能 tab 都用上,知道是因为重渲导致 deep 本身比较了两次耗时,用了挺多时间一层层排查,确保只渲一次,但未来这个平衡又可能随着需求迭代不经意间被打破。
    songray
        2
    songray  
       2025 年 7 月 9 日
    @Chuckle 用 Mobx 或者直接一步到位 Preact + Preact signal ,目前用下来 Preact 没什么兼容问题。
    crysislinux
        3
    crysislinux  
       2025 年 7 月 9 日 via Android
    当然是随缘啦。react 和 vue 其实还好,在 signal 时代之前的 angular ,一个页面尤其是有 form 的页面,渲染稳定之前跑几十次 change detection 也是稀松平常。
    Chuckle
        4
    Chuckle  
    OP
       2025 年 7 月 9 日
    @songray 个人项目试试,但司内是 umi+自己的 react 框架,不知道纯 react 怎么解决性能问题
    Dreamful
        5
    Dreamful  
       2025 年 7 月 9 日
    蹲一下,我也想问大家个问题
    你们用 vue 把弹窗封装成组件的时候,关闭弹窗的方式是怎么样的?
    我感觉父组件控制 visible 变量传给子组件,并且把这个变量绑定 v-if ,这样每次关闭组件重新打开都会初始化一次,不用考虑子组件初始化问题( ps:没有弹窗关闭后缓存数据的需求)
    之所以问这个是因为公司有一个大屏项目是实习生写的,所有请求都写在父组件,然后子组件更新数据的时候都得调用父组件的方法来请求。 有些弹窗组件也是跟随大屏打开的时候就初始化了,导致有些变量 provide/inject 接收不到
    linkopeneyes
        6
    linkopeneyes  
       2025 年 7 月 9 日   ❤️ 1
    linkopeneyes
        7
    linkopeneyes  
       2025 年 7 月 9 日
    当然是不管,卡的不行再去管,当然前期什么虚拟滚动,Immer 默认都用上的情况下应该不会怎么卡的
    yb2313
        8
    yb2313  
       2025 年 7 月 9 日
    当然是命令 ai 狠狠优化了
    liuidetmks
        9
    liuidetmks  
       2025 年 7 月 9 日   ❤️ 1
    过早优化是万恶之源

    卡了再说
    songray
        10
    songray  
       2025 年 7 月 9 日
    @Chuckle 那无解了兄弟。
    React 两大原罪,一是 state 颗粒度太大,二是从根开始 diff ,上游的问题你没法从下游解决。
    NessajCN
        11
    NessajCN  
       2025 年 7 月 9 日
    变状态重渲染的只是状态所在的组件,你把组件拆细一点不就完了
    alleluya
        12
    alleluya  
       2025 年 7 月 9 日   ❤️ 1
    dan 不是说过么 90%的情况下都不需要考虑性能问题 哪怕重复渲染两次 换到国内业务开发的视角 业务新需求在不断迭代的情况下谁会过分关注性能问题 没到卡的不行的程度都不用管 问就是客户电脑配置不行
    SanjinGG
        13
    SanjinGG  
       2025 年 7 月 9 日
    @Dreamful 反正我目前是弹窗暴露方法,直接调用方法,参考 element 的,套组件的话用到的地方都要引入,还要管理一堆状态
    microscopec
        14
    microscopec  
       2025 年 7 月 9 日
    别担心,我们已经一个人接 20 个项目了,每天对接 3 个后端写接口,慢慢的以后不会再有机会多人合作一个项目了
    shintendo
        15
    shintendo  
       2025 年 7 月 9 日
    @Dreamful
    我喜欢的做法:弹窗组件自己管理 visible ,自己发请求,自己管一切,对外暴露一个 open 方法,父组件调 open 打开弹窗。
    rb6221
        16
    rb6221  
       2025 年 7 月 9 日
    有最佳实践也不代表你们能执行啊,先把 code review 搞起来再说吧
    zhhbstudio
        17
    zhhbstudio  
       2025 年 7 月 9 日
    @Dreamful #5
    1. visible 问题
    我一般都是直接通过 v-model 传 visible ,内部通过 computed 处理 visible , 更新 visible 就 emit 事件出来。v-if 重新渲染是我不太能理解的方案(仔细想了一下,是因为非必要不渲染?
    2. 子组件自用数据肯定是自己处理。如果是类似新增这种弹窗,那再传一个 @refresh="getData" 子组件更新成功再 emit (‘refresh’)

    provide/inject 用的很少
    xiaoming1992
        18
    xiaoming1992  
       2025 年 7 月 9 日 via Android
    看看 useTransition 能不能缓解卡顿
    shui14
        19
    shui14  
       2025 年 7 月 9 日
    你应该把不同类型的表单抽出去,而不是想着生成表单。表单特殊,就是 jquery 都无解
    早几年怎么吐槽 antd 的,一大半就是因为它的表单过度封装
    题外话,回复楼上,人家 pmndrs resium rn 都能优化,为什么不行
    shunia
        20
    shunia  
       2025 年 7 月 9 日
    把过于复杂,性能要求高的 react 组件抽出来,做成高性能的 react 组件或者直接做成原生 html+js 组件。

    什么都用 react 或者 vue 只会害了你。
    shunia
        21
    shunia  
       2025 年 7 月 9 日   ❤️ 1
    @shunia #20 加一句:react 或者 vue 等等几乎所有框架,都不是为了性能而生的。
    kakki
        22
    kakki  
       2025 年 7 月 9 日
    给弹窗组件一个 ref, 直接调用 ref 方法.鸡零狗碎的状态太多就很烦,能自我管理尽量自我管理.
    lanten
        23
    lanten  
       2025 年 7 月 9 日
    最佳实践是什么,是问出来的吗?这个推荐那个推荐,不如自己推荐
    Gilfoyle26
        24
    Gilfoyle26  
       2025 年 7 月 9 日
    @liuidetmks #9 经典
    leokun
        25
    leokun  
       2025 年 7 月 9 日
    从业务角度来说,表单的性能高低不会有一毛钱的影响
    cwwx2022
        26
    cwwx2022  
       2025 年 7 月 9 日
    我在网上看到了这个 https://shame-of-react.pages.dev/ ,是关于 react 的
    hahaFck
        27
    hahaFck  
       2025 年 7 月 9 日
    @shintendo 这样会有另外一个问题,就是弹窗关闭了,弹窗组件没有摧毁掉,在重新打开后,数据还是跟上次一样的,每次打开都是上次打开的结果,也挺烦的。
    liuliancc
        28
    liuliancc  
       2025 年 7 月 9 日
    @Dreamful #5 我一般父元素通过双向绑定 v-mode visible 控制,子元素 prop visible 、emit('change:visible', true/false),也不会重新渲染、丢失动画
    jianv3
        29
    jianv3  
       2025 年 7 月 9 日
    虚拟列表。 几万条数据也无所谓
    anivie
        30
    anivie  
       2025 年 7 月 9 日
    @liuidetmks 真的卡的时候想去优化已经不可能了,只有重写,大部分卡的批爆的网页都是这么来的
    AV1
        31
    AV1  
       2025 年 7 月 9 日
    换个角度想,当你的数据有成千上万行时,你应该考虑提供分页、排序、搜索、筛选、摘要功能,方便用户定位到想要的数据。
    Chuckle
        32
    Chuckle  
    OP
       2025 年 7 月 9 日
    把 rxjs 和 context 结合起来咋样,需要暴露和传递的数据,别 props 一层层传状态,让组件订阅所需外部状态的变化,而不是从 props 中获取,感觉有空可以琢磨下
    Chuckle
        33
    Chuckle  
    OP
       2025 年 7 月 9 日
    @Chuckle #32 还真有现成的 https://react-rxjs.org/docs/getting-started ,确实能想到估计也有人做过了(
    RedNax
        34
    RedNax  
       2025 年 7 月 10 日
    想集成 rxjs 可以看看 focal:
    https://github.com/grammarly/focal
    Dreamful
        35
    Dreamful  
       2025 年 7 月 10 日
    @liuliancc 主要是组件加载时机,有时候不希望子组件一开始就加载,每次打开都重新加载。感觉不如父组件直接加 v-if 省事
    realJamespond
        36
    realJamespond  
       2025 年 7 月 10 日
    换 zustand 细粒度更新,直接子组件之间互相作用,绕过 state+context 从根组件全刷
    lstmxx
        37
    lstmxx  
       2025 年 7 月 10 日
    @hahaFck 写一个 reset 函数,close 的时候调用吧,我是这么做的
    GiantHard
        38
    GiantHard  
       2025 年 10 月 23 日
    @Chuckle #32 如果打算用 Context 传递 Observable 状态,不如用 mobx ,因为 rxjs 的 API 过于庞大(各种 operator, subject ),而 mobx 的 API 则要精简很多( observable, aciton, autorun/reaction, computed )。

    另外,mobx 还有 babel/swc 的插件 https://github.com/christianalfoni/mobx-react-observer ,可以自动将组件包装成 observer ,代码中会少很多语法噪音。

    除此之外,mobx 相比 rxjs 还提供了状态更新 transaction https://mobx.js.org/api.html#transaction ,这在很多时候也是避免由于重复渲染导致性能劣化的有效方法。

    不过,选择用 mobx 这样的基于可变数据结构的状态库,就意味着你需要放弃正宗 React 味儿,会大量地打破 rule of hooks 。
    关于   ·   帮助文档   ·   自助推广系统   ·   博客   ·   API   ·   FAQ   ·   Solana   ·   3173 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 38ms · UTC 13:53 · PVG 21:53 · LAX 05:53 · JFK 08:53
    ♥ Do have faith in what you're doing.