Skip to content

[devtools] Prevent incorrect render detection for user components in didFiberRender (#33423)#94

Closed
everettbu wants to merge 1 commit into
mainfrom
fix/devtools-profiler-render-highlight-2
Closed

[devtools] Prevent incorrect render detection for user components in didFiberRender (#33423)#94
everettbu wants to merge 1 commit into
mainfrom
fix/devtools-profiler-render-highlight-2

Conversation

@everettbu

@everettbu everettbu commented Dec 12, 2025

Copy link
Copy Markdown

Mirror of facebook/react#33434
Original author: developerjhp


Summary

Fixes false positive rendering detection in React DevTools Profiler by improving the didFiberRender function to accurately detect when user components actually re-render, preventing misleading "The parent component rendered" messages.

Problem

Previously, React DevTools would incorrectly mark components as "rendered" even when they didn't actually re-render due to bailouts. This happened because the didFiberRender function only checked the PerformedWork flag, but React can set this flag even during bailout scenarios.

Example scenario:

  • Parent component state changes
  • Sibling component with unchanged props shows "The parent component rendered"
  • But the sibling component console.log shows it didn't actually re-render

Solution

Enhanced didFiberRender function for user components (ClassComponent, FunctionComponent, etc.):

// Before
const PerformedWork = 0b000000000000000000000000001;
return (getFiberFlags(nextFiber) & PerformedWork) === PerformedWork;

// After  
if ((getFiberFlags(nextFiber) & PerformedWork) === 0) {
  return false;
}
if (
  prevFiber != null &&
  prevFiber.memoizedProps === nextFiber.memoizedProps &&
  prevFiber.memoizedState === nextFiber.memoizedState &&
  prevFiber.ref === nextFiber.ref
) {
  // React may mark PerformedWork even if we bailed out. Double check
  // that inputs actually changed before reporting a render.
  return false;
}
return true;

This change ensures that:

  1. We first check the PerformedWork flag (performance optimization)
  2. Then verify that props/state/ref actually changed (accuracy check)
  3. Only report rendering when inputs genuinely changed

Testing

Test Setup:
Used the following test case with independent Count and Greeting components:

const Count = () => {
    const [count, setCount] = useState(0);
    console.log('Count Component Rerendered');
    return (
        <button onClick={() => setCount(c => c + 1)}>
            Count: {count}
        </button>
    );
};

const Greeting = () => {
    console.log('Greeting Component Rerendered');
    return <span>Hello World!</span>;
};

const App = () => {
    const [appState, setAppState] = useState(0);
    console.log('App Component Rerendered');
    
    return (
        <main>
            <div>App State: {appState}</div>
            <button onClick={() => setAppState(s => s + 1)}>
                App Rerender Trigger (All children rerender)
            </button>
            <hr />
            <Count />
            <div>
                <Greeting />
            </div>
        </main>
    );
};

Test Results:
Tested and verified with this code

// Before

Screen.Recording.2025-06-04.at.13.17.03.mov

// After

Screen.Recording.2025-06-04.at.13.17.35.mov

Before Fix:

  • Click Count button → Console shows only "Count Component Rerendered"
  • DevTools Profiler → Greeting component incorrectly shows "The parent component rendered"

After Fix:

  • Click Count button → Console shows only "Count Component Rerendered"
  • DevTools Profiler → Greeting component correctly shows no rendering information

Related

This change specifically targets user components (Function/Class components) and maintains existing behavior for host components, ensuring accurate rendering detection across the React component tree.

Fixes react/react#33423 , react/react#19732

Improve rendering detection accuracy by adding actual input change verification
for user components that have PerformedWork flag set. This prevents showing
"The parent component rendered" message and highlight updates for components
that didn't actually re-render due to bailouts.

- Add props/state/ref comparison for user components after PerformedWork check
- Restore original props comparison logic for host components
- Fixes issue where bailout components were incorrectly marked as rendered
@greptile-apps

greptile-apps Bot commented Dec 12, 2025

Copy link
Copy Markdown

Greptile Overview

Greptile Summary

Fixed false positive rendering detection in React DevTools Profiler by enhancing the didFiberRender function to verify that props, state, and refs actually changed before reporting a render. Previously, components could be incorrectly marked as "rendered" during bailout scenarios where React set the PerformedWork flag but the component didn't actually re-execute.

Key Changes:

  • Added identity checks for memoizedProps, memoizedState, and ref between previous and next fibers
  • Returns false when PerformedWork is set but inputs haven't changed (bailout scenario)
  • Maintains existing behavior for host components in the default case

Minor Issue:

  • Comment on line 1883 is outdated and should be updated to reflect that bailouts are now properly detected

Confidence Score: 4/5

  • This PR is safe to merge with minimal risk
  • The fix correctly addresses the false positive rendering issue using standard React Fiber identity checks (=== for memoizedProps/State/ref). Logic is sound and consistent with the default case for host components. Only minor issue is an outdated comment that doesn't affect functionality. The PR includes thorough testing documentation with before/after videos.
  • No files require special attention

Important Files Changed

File Analysis

Filename Score Overview
packages/react-devtools-shared/src/backend/fiber/renderer.js 4/5 Fixed false positive render detection in didFiberRender by adding props/state/ref equality checks after PerformedWork flag. One outdated comment needs updating.

@greptile-apps greptile-apps Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

1 file reviewed, no comments

Edit Code Review Agent Settings | Greptile

@everettbu everettbu added Resolution: Stale Automatically closed due to inactivity and removed Resolution: Stale Automatically closed due to inactivity labels Dec 24, 2025
@github-actions

Copy link
Copy Markdown

This pull request has been automatically marked as stale. If this pull request is still relevant, please leave any comment (for example, "bump"), and we'll keep it open. We are sorry that we haven't been able to prioritize reviewing it yet. Your contribution is very much appreciated.

@github-actions github-actions Bot added the Resolution: Stale Automatically closed due to inactivity label Mar 24, 2026
@github-actions

Copy link
Copy Markdown

Closing this pull request after a prolonged period of inactivity. If this issue is still present in the latest release, please ask for this pull request to be reopened. Thank you!

@github-actions github-actions Bot closed this Mar 31, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CLA Signed Resolution: Stale Automatically closed due to inactivity

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Bug: profiler incorrectly reports 'The parent component rendered'

2 participants