Skip to content

perf: Not render fully Popup on init #540

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
May 15, 2025
Merged

perf: Not render fully Popup on init #540

merged 4 commits into from
May 15, 2025

Conversation

zombieJ
Copy link
Member

@zombieJ zombieJ commented May 14, 2025

ref https://github.com/react-component/trigger/pull/538/files#r2077353602

Summary by CodeRabbit

  • 新功能

    • 新增了针对弹窗渲染性能的测试用例,验证在不同条件下弹窗的渲染行为。
  • 修复

    • 优化了弹窗的渲染逻辑,仅在需要时才渲染弹窗内容,提升性能。
  • 重构

    • 简化了组件结构,移除了冗余的组件包装,支持更直接的 ref 转发。
    • 调整了部分组件的初始状态设置。

Copy link

coderabbitai bot commented May 14, 2025

Walkthrough

本次变更主要涉及对弹出组件的渲染控制优化、示例代码的 ref 转发与组件结构调整,以及新增针对性能的测试用例。弹出组件现在仅在需要时才渲染,示例组件简化了 ref 逻辑,测试文件验证了弹出渲染的性能行为。

Changes

文件/文件组 变更摘要
docs/examples/simple.tsx InnerTarget 组件改为 forwardRef,支持 ref 转发;移除 RefTarget 组件;mask 初始值从 true 改为 falseTrigger 直接使用 InnerTarget
src/index.tsx 优化弹出组件渲染逻辑:通过 rendedRef 仅在 forceRendermergedOpeninMotion 为真时渲染弹出内容。
tests/perf.test.tsx 新增性能相关测试:验证弹出组件按需渲染、forceRender 行为、隐藏后不卸载弹出组件等性能特性。

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant Trigger
    participant Popup

    User->>Trigger: 初始渲染
    alt forceRender/mergedOpen/inMotion 为真
        Trigger->>Popup: 渲染 Popup
    else
        Note over Trigger: 不渲染 Popup
    end
    User->>Trigger: 触发显示(如点击)
    Trigger->>Popup: 渲染 Popup
Loading

Suggested reviewers

  • afc163

Poem

🐇
小兔敲键盘,代码悄然变,
弹窗只在必要时才现身,
Ref 转发轻松又自然,
测试护航性能稳,
代码世界更清新!

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 ESLint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

docs/examples/simple.tsx

Oops! Something went wrong! :(

ESLint: 8.57.1

ESLint couldn't find the plugin "eslint-plugin-react".

(The package "eslint-plugin-react" was not found when loaded as a Node module from the directory "".)

It's likely that the plugin isn't installed correctly. Try reinstalling by running the following:

npm install eslint-plugin-react@latest --save-dev

The plugin "eslint-plugin-react" was referenced from the config file in ".eslintrc.js » /node_modules/.pnpm/@umijs[email protected][email protected]/node_modules/@umijs/fabric/dist/eslint.js".

If you still can't figure out the problem, please stop by https://eslint.org/chat/help to chat with the team.

src/index.tsx

Oops! Something went wrong! :(

ESLint: 8.57.1

ESLint couldn't find the plugin "eslint-plugin-react".

(The package "eslint-plugin-react" was not found when loaded as a Node module from the directory "".)

It's likely that the plugin isn't installed correctly. Try reinstalling by running the following:

npm install eslint-plugin-react@latest --save-dev

The plugin "eslint-plugin-react" was referenced from the config file in ".eslintrc.js » /node_modules/.pnpm/@umijs[email protected][email protected]/node_modules/@umijs/fabric/dist/eslint.js".

If you still can't figure out the problem, please stop by https://eslint.org/chat/help to chat with the team.

tests/perf.test.tsx

Oops! Something went wrong! :(

ESLint: 8.57.1

ESLint couldn't find the plugin "eslint-plugin-react".

(The package "eslint-plugin-react" was not found when loaded as a Node module from the directory "".)

It's likely that the plugin isn't installed correctly. Try reinstalling by running the following:

npm install eslint-plugin-react@latest --save-dev

The plugin "eslint-plugin-react" was referenced from the config file in ".eslintrc.js » /node_modules/.pnpm/@umijs[email protected][email protected]/node_modules/@umijs/fabric/dist/eslint.js".

If you still can't figure out the problem, please stop by https://eslint.org/chat/help to chat with the team.

Tip

⚡️ Faster reviews with caching
  • CodeRabbit now supports caching for code and dependencies, helping speed up reviews. This means quicker feedback, reduced wait times, and a smoother review experience overall. Cached data is encrypted and stored securely. This feature will be automatically enabled for all accounts on May 16th. To opt out, configure Review - Disable Cache at either the organization or repository level. If you prefer to disable all data retention across your organization, simply turn off the Data Retention setting under your Organization Settings.

Enjoy the performance boost—your workflow just got faster.

✨ Finishing Touches
  • 📝 Generate Docstrings

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@zombieJ zombieJ mentioned this pull request May 14, 2025
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (2)
src/index.tsx (1)

658-708: 条件渲染实现优化了初始化性能

使用 rendedRef.current 作为条件来控制 Popup 组件的渲染是一个很好的优化。这确保了只有在需要时(打开状态、强制渲染或处于动画过渡中)才会渲染 Popup 组件树,避免了不必要的初始化开销。

这与 PR 标题 "perf: Not render fully Popup on init" 的目标完全一致,是一个有效的性能改进。

这种按需渲染的模式非常适合用于其他类似的组件,特别是那些内容复杂但不总是可见的组件。这种优化在大型应用中尤为重要,可以显著减少初始渲染时间和内存使用。

docs/examples/simple.tsx (1)

3-3: 改进类型导入语法

ActionType 改为类型导入可以在构建时优化掉类型信息,减小最终的包体积。这是 TypeScript 中的最佳实践。

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between e2e2a9c and 868a6ad.

📒 Files selected for processing (3)
  • docs/examples/simple.tsx (4 hunks)
  • src/index.tsx (2 hunks)
  • tests/perf.test.tsx (1 hunks)
🔇 Additional comments (8)
src/index.tsx (1)

598-600: 添加性能优化的 rendedRef 实现

这个变更通过引入 rendedRef 引用来优化性能,使得 Popup 组件只在必要时才进行渲染。当 forceRendermergedOpeninMotion 任一为真时,才会标记为需要渲染。这是一个有效的性能优化,可以减少不必要的渲染操作。

docs/examples/simple.tsx (3)

46-64: 使用 React.forwardRef 优化组件引用传递

InnerTarget 组件改为使用 React.forwardRef 是一个很好的改进,这样可以正确地将引用传递给底层 DOM 元素。这种模式使组件更容易与 React 的引用系统集成,特别是在与 Trigger 组件配合使用时。


88-88: 将 mask 默认值更改为 false

mask 的初始值从 true 改为 false 使示例更简洁。这个变更与主要的性能优化变更相符,因为不显示遮罩也能减少初始渲染的元素数量。


377-377: 简化组件结构

直接使用 <InnerTarget /> 替代之前可能使用的 <RefTarget /> 组件,简化了组件层次结构。这种简化与 PR 的目标一致,减少了不必要的组件嵌套,提高了代码的可读性和性能。

tests/perf.test.tsx (4)

7-15: 模拟 Popup 组件以跟踪实例化次数

这段代码通过模拟 Popup 组件来跟踪其实例化次数,是一个测试性能优化效果的好方法。通过在全局对象上记录调用次数,可以有效验证条件渲染的行为。


52-65: 验证未打开时不创建 Popup

这个测试用例验证了当 Popup 未打开时,不会创建 Popup 组件实例,这直接测试了 rendedRef 条件渲染的行为。测试先确认初始状态下 Popup 未被创建,然后触发点击事件后才创建,这完全符合性能优化的预期。


67-79: 验证 forceRender 属性的行为

这个测试验证了即使在 Popup 未打开的情况下,设置 forceRendertrue 也会创建 Popup 组件。这确保了 rendedRef 条件正确处理了 forceRender 属性,与实现中的逻辑一致。


81-100: 验证隐藏时保留 Popup 渲染

这个测试确保了当 Popup 从可见变为隐藏状态时,Popup 组件仍然保持渲染状态而不是被卸载。这对于保证过渡动画的平滑性很重要,同时也验证了 rendedRef 在此场景下的正确行为。

Copy link

codecov bot commented May 14, 2025

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 97.69%. Comparing base (e2e2a9c) to head (868a6ad).
Report is 1 commits behind head on master.

Additional details and impacted files
@@            Coverage Diff             @@
##           master     #540      +/-   ##
==========================================
+ Coverage   97.68%   97.69%   +0.01%     
==========================================
  Files          12       12              
  Lines         777      781       +4     
  Branches      230      225       -5     
==========================================
+ Hits          759      763       +4     
  Misses         18       18              

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@zombieJ zombieJ merged commit 052b2ae into master May 15, 2025
10 checks passed
@zombieJ zombieJ deleted the simple branch May 15, 2025 08:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants