PAYATHON 2026

React Activity 保持 mode="visible" 能提升性能吗?

数据小陈

结论

仅用 <Activity mode="visible"> 包住 CompactView,即使它被 CSS 隐藏,React 也不会因此自动减少渲染或暂停 Effects。对于纯客户端渲染,这样做不会直接优化隐藏视图。

如果应用使用 SSR 和 hydration,始终为 visible 的 Activity 边界也可能通过参与 Selective Hydration,改善页面加载期间的交互响应。是否有实际收益,需要结合应用测量。React 官方文档

为什么 CSS 隐藏不会触发 Activity 的优化

示例中的 ExtendedView 和 CompactView 都在 React 组件树中,container query 只决定它们在浏览器中如何显示。

display: none 会让对应内容不参与布局和绘制,但不会卸载 React 组件,也不会自动停止其中的 Effects、订阅或定时器。React 不会根据 container query 的匹配结果自动修改 Activity 的 mode。

因此,即使 CompactView 在页面上不可见,下面的边界仍处于 visible 模式:

<Activity mode="visible">
  <CompactView />
</Activity>

visible 是默认值,省略 mode 与显式设置它含义相同。Activity 属性说明

用户大多使用大屏幕,只能说明 CompactView 较少显示,不能据此判断这层包装会带来多少性能收益。

怎样减少隐藏视图的工作

如果希望隐藏视图保留状态,同时清理其 Effects,需要让 React 获得与 container query 一致的显示条件,再据此切换 mode。

下面假设 isCompact 已由外部根据实际容器尺寸计算,且 ExtendedView、CompactView 已在当前文件中定义或导入:

import { Activity } from 'react';

function ResponsiveViews({ isCompact }) {
  return (
    <>
      <Activity mode={isCompact ? 'hidden' : 'visible'}>
        <ExtendedView />
      </Activity>
      <Activity mode={isCompact ? 'visible' : 'hidden'}>
        <CompactView />
      </Activity>
    </>
  );
}

进入 hidden 模式后,Activity 会保留状态和 DOM,清理 Effects,并以较低优先级处理隐藏子树的渲染;恢复 visible 时会重新建立 Effects。hidden 不意味着完全停止渲染,也不会释放整棵子树占用的内存。Activity 行为说明

实现时需要注意:

  • container query 依据容器尺寸,不能直接用屏幕或窗口宽度替代。可以通过 ResizeObserver 观察对应容器,再按相同规则计算 isCompact。
  • CSS 与 JavaScript 要使用一致的断点和判断条件,否则可能出现 CSS 已显示、Activity 仍隐藏的情况。
  • Effects 中创建的订阅、定时器等资源,需要在 cleanup 中释放。

如果切换视图时不需要保留各自的内部状态,可以直接条件渲染:

return isCompact ? <CompactView /> : <ExtendedView />;

这样不会挂载未选中的视图,但切换时会卸载旧视图,其内部状态也会丢失。

如何判断是否值得改动

如果想解决 SSR 页面加载期间交互迟缓的问题,可以测量 visible Activity 边界对 hydration 的影响;如果隐藏视图仍在运行订阅或发生昂贵更新,可以考虑动态切换 hidden 或条件渲染。

使用 React DevTools Profiler 和浏览器 Performance 面板,对比初次加载、容器尺寸切换以及常见数据更新的情况。原问题没有提供 SSR 配置、组件开销或测量结果,因此无法承诺这次包装能带来性能提升。

备注:内容仅供参考。