ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Papermark 渲染性能实践:用 React `<Activity>` 组件保留状态、消除高频显隐切换的昂贵重渲染

Papermark 渲染性能实践:用 React `<Activity>` 组件保留状态、消除高频显隐切换的昂贵重渲染 后端前端企业应用【免费下载链接】papermarkPapermark is the open-source DocSend alternative and secure data rooms with built-in analytics and custom domains.项目地址https://gitcode.com/GitHub_Trending/pa/papermark点击查看免费下载导读本文围绕 Vercel React Best Practices 规则集中的rendering-activity规则展开讲解如何利用 React 的Activity组件为频繁在显示与隐藏之间切换、且渲染成本较高的组件保留 DOM 与内部状态避免每次开关都触发卸载重建和昂贵的重渲染。同时结合 Papermark 仓库中真实的显隐切换场景查看器自动隐藏控制条、空闲暂停遮罩、响应式侧边栏等给出可直接落地的用法示例、与条件渲染 /display: none的取舍分析以及升级 React 19 前后的注意事项。读完本文你将掌握Activity modevisible | hidden的完整用法、判断哪些组件值得用 Activity 包裹的评估标准以及它在当前项目中的潜在应用位置。规则背景Vercel React 性能规则集中的一分子本规则出自仓库内的 .agents/skills/vercel-react-best-practices 技能包它由 Vercel 工程团队维护是一套涵盖 57 条规则的 React / Next.js 性能优化指南按影响优先级分为 8 大类别优先级类别影响前缀1消除 WaterfallCRITICALasync-2包体积优化CRITICALbundle-3服务端性能HIGHserver-4客户端数据获取MEDIUM-HIGHclient-5重渲染优化MEDIUMrerender-6渲染性能MEDIUMrendering-7JavaScript 性能LOW-MEDIUMjs-8高级模式LOWadvanced-rendering-activity属于渲染性能Rendering Performance类别与其他渲染类规则如 rendering-content-visibility 用content-visibility: auto延迟屏幕外渲染、rendering-conditional-render 用三元表达式替代避免渲染出0/NaN并列。该规则声明的impact为MEDIUM其核心收益是保留状态 / 保留 DOMpreserves state/DOM。核心问题为什么频繁 show/hide 会带来昂贵的重渲染与状态丢失在 React 中显示 / 隐藏最常见的两种实现方式各有代价条件渲染卸载 / 挂载{isOpen ExpensiveMenu /}或三元表达式。组件在隐藏时被完全卸载DOM 被移除、内部useState状态、滚动位置、表单输入、动画进度等全部丢失再次显示时要从零开始重建、重新执行挂载副作用如订阅、测量、数据请求。对渲染成本高的组件长列表、复杂图表、PDF/表格查看器等每次开关都是一次完整的销毁 重建。CSS 隐藏display: none/visibility: hiddenDOM 与组件状态得以保留但display: none会触发浏览器布局重排且组件依然参与 React 的协调与渲染流程如果父组件因其他原因重渲染隐藏中的子树仍可能被重复渲染。对于频繁切换可见性的昂贵组件上述两种方式要么丢状态、要么浪费渲染。这正是Activity的适用场景它让组件在隐藏时保持挂载、跳过渲染、保留状态仅在状态真正变化时付出一次协调代价从而避免昂贵的重渲染和状态丢失——这正是原规则impactDescription: preserves state/DOM的含义。标准用法Activity modevisible | hidden规则文档给出的标准用法非常精简可直接复制到组件中import { Activity } from react function Dropdown({ isOpen }: Props) { return ( Activity mode{isOpen ? visible : hidden} ExpensiveMenu / /Activity ) }关键点拆解mode是受控属性取值只有两个visible子树正常渲染、可交互、参与布局hidden子树保持挂载但不渲染内容组件状态state、ref、DOM 节点引用得以保留再次切回visible时无需重新初始化。Activity包裹的是昂贵子树真正成本高、需要保状态的组件菜单、弹窗、抽屉、图表、查看器放在内部外部只负责根据业务状态切换mode。状态与isOpen解耦isOpen只决定mode不决定是否挂载因此下拉菜单的选中项、搜索输入框的草稿、面板的滚动位置在隐藏后都不会丢失。从使用契约上看Activity提供的是一种保留型显隐语义可以把它理解为带状态保留的显示/隐藏开关它既不像条件渲染那样卸载子树也不像display: none那样让隐藏子树继续参与无谓的渲染流程。三种显隐方案的对比与选型方案DOM 是否保留组件状态是否保留隐藏时的渲染成本适用场景条件渲染/ 三元否卸载否全部丢失无已卸载但显示时重建成本高一次性展示、无需保状态、渲染成本低的轻组件CSSdisplay: none是是隐藏子树仍随父组件重渲染而渲染可能触发重排需要保状态但显隐频率低、子树不重的场景ReactActivity是是隐藏时跳过子树渲染频繁切换显隐的昂贵组件是规则推荐的首选选型判断可归纳为一条经验法则如果组件渲染贵且切换频繁、并且隐藏后必须保留状态就用Activity如果只是偶尔显示一次的轻量内容条件渲染反而更省内存。Papermark 中的高频显隐场景Activity 的潜在落点当前仓库package.json基于Next.js 14.2 React 18.3因此ActivityReact 19 提供的组件在仓库源码中尚未直接使用但仓库中存在多处昂贵组件 频繁显隐的真实场景正是升级到 React 19 后应用本规则的候选位置。场景一查看器的自动隐藏控制条图片/幻灯查看器实现了鼠标活动时显示控制条、空闲数秒后自动隐藏的交互例如 image-viewer.tsxconst { visible: controlsVisible, reveal: revealControls } ...控制条在显示/隐藏之间随用户操作频繁切换而查看器本体大图、缩放画布渲染成本很高。这类频繁切换 昂贵子树的组合正是Activity mode{controlsVisible ? visible : hidden}的理想目标——切换mode时查看器画布保持挂载、缩放与滚动状态不丢失不再因为控制条显隐而触发昂贵子树的重复渲染。场景二空闲暂停遮罩AwayPoster查看器内置空闲自动暂停会话的提示遮罩组件 away-poster.tsx其显隐实现为条件渲染if (!isVisible) return null;并在各查看器中被这样调用以 pdf-default-viewer.tsx 为例AwayPoster isVisible{isInactive} inactivityThreshold{...} onDismiss{updateActivity} /其中isInactive由 safe-page-view-tracker.ts 中的空闲检测逻辑驱动——用户停止活动一段时间后变为true恢复活动后变回false遮罩随之反复出现与消失。这类会话级频繁触发的遮罩若换成Activity可避免遮罩反复卸载/重建带来的动画与 DOM 开销也让遮罩背后的查看器内容在遮罩显示期间保持状态与挂载。场景三响应式侧边栏与移动端抽屉dataroom-viewer.tsx 中通过 Tailwind 的hidden md:block、lg:hidden等断点类在桌面 / 移动端之间切换侧边栏与抽屉的可见性同时使用aria-hiddentrue标记隐藏内容。这类随断点或交互频繁切换的导航面板同样属于 Activity 的候选范围不过需要注意Activity 的mode需要由 JS 状态驱动纯 CSS 断点场景若要应用需要先把断点状态提升为 React 状态。需要注意的命名混淆在仓库中搜索Activity时命中的大部分代码如 safe-page-view-tracker.ts、tracking-config.ts是用户活动检测user activity tracking——用于统计文档查看时长、空闲时长与本文讨论的 ReactActivity组件完全无关两者不要混淆。在 Papermark 中落地本规则的前提与步骤由于Activity是 React 19 的组件当前基于 React 18.3.1 的仓库package.json 中react: ^18.3.1、next: ^14.2.35无法直接使用。落地路径如下升级 React 到 19.x 并配套升级 Next.jsActivity依赖 React 19 的保留型渲染机制需同步升级到支持 React 19 的 Next.js 版本并回归验证 pages、components 中的现有组件尤其是 view/viewer 下依赖 react-pdf、react-zoom-pan-pinch、react-notion-x 等第三方库的查看器。挑选高频显隐的昂贵组件优先从上述控制条、AwayPoster 遮罩、响应式面板入手将显隐状态controlsVisible、isInactive、isOpen等映射为mode属性。保持渐进式接入先对单个组件试点用 React DevTools 的 Profiler 对比切换前后的渲染耗时与组件挂载次数确认收益后再推广。在完成升级之前如果希望先获得保留状态的收益可以采用过渡手段保持组件始终挂载、仅切换 CSS 类控制可见性类似display: none的降级方案但这无法获得 Activity 隐藏时跳过子树渲染的完整收益——这也是后续升级 React 19 后切换为Activity的直接理由。何时不该用ActivityActivity并非万能以下情况应保持条件渲染或 CSS 隐藏组件渲染成本极低一个图标、一段文本Activity 带来的挂载保留反而增加内存占用收益可忽略隐藏后必须释放资源如视频播放器、WebSocket 连接、定时器等需要在隐藏时主动清理的场景卸载比保挂载更合适需要 SSR/SEO 的内容Activity 的保留语义面向客户端交互态服务端首屏内容仍应正常渲染从规则集的定位看它属于渲染性能优化而非服务端渲染范畴显隐频率极低如一年一次的引导页一次性的挂载/卸载成本可忽略不必为此引入保留型渲染。小结rendering-activity规则给出了一条简洁而高价值的性能准则对频繁切换可见性的昂贵组件用Activity modevisible | hidden代替条件渲染换取状态与 DOM 的保留和隐藏时跳过渲染的双重收益。在 Papermark 的查看器体系中自动隐藏控制条、空闲暂停遮罩、响应式面板都是该规则的天然落点待项目升级到 React 19 后可据此逐步替换现有if (!isVisible) return null与hidden类方案在保留交互状态的同时削减高频显隐带来的渲染开销。更多同类别规则可继续查阅 .agents/skills/vercel-react-best-practices 中的渲染性能章节。赞分享后端前端企业应用【免费下载链接】papermarkPapermark is the open-source DocSend alternative and secure data rooms with built-in analytics and custom domains.项目地址https://gitcode.com/GitHub_Trending/pa/papermark点击查看免费下载相关推荐使用 React Activity 组件实现高效的显隐切换与状态保留cherry-studio 渲染性能实践使用 React Activity 组件实现高效的显隐切换与状态保留cherry studio 渲染性能实践 导读 在 React 应用中频繁切换显隐状态AI 应用大模型桌面应用本地部署RAG用 React Activity 组件管理显隐切换在 Langfuse 前端保留昂贵组件的状态与 DOM用 React Activity 组件管理显隐切换在 Langfuse 前端保留昂贵组件的状态与 DOM Activity 是 React 19.2 起提人工智能LLMOps可观测性AI 评测LLM 网关后端前端React 19 Activity 组件实战用保留式隐藏替代条件卸载告别昂贵组件的状态丢失与重复渲染React 19 Activity 组件实战用保留式隐藏替代条件卸载告别昂贵组件的状态丢失与重复渲染 导读 本文围绕 Vercel React Best音视频桌面应用后端上一篇Qwen3-VL-30B-A3B-Thinking从视觉感知到智能执行的多模态革命下一篇nacos-docker高级配置自定义application.properties实现生产级部署创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表