Skip to content

[devtools]: Prevent false positive render detection in profiler (#33423, #19732)#111

Closed
everettbu wants to merge 2 commits into
mainfrom
fix/devtools-profiler-render-highlight-3
Closed

[devtools]: Prevent false positive render detection in profiler (#33423, #19732)#111
everettbu wants to merge 2 commits into
mainfrom
fix/devtools-profiler-render-highlight-3

Conversation

@everettbu

@everettbu everettbu commented Dec 12, 2025

Copy link
Copy Markdown

Mirror of facebook/react#33964
Original author: developerjhp


Summary

Fixes a bug in React DevTools where the profiler incorrectly reported sibling components as re-rendered when they were nested under HostComponents (like <div>) that get filtered out by DevTools. This affected profiler data collection, render highlighting, and inspector cache management.

Background

React DevTools filters out DOM elements (HostComponents) by default to focus on user components. However, this filtering created a blind spot where sibling components under the same HostComponent parent would be incorrectly reported as re-rendered even when their Fiber objects remained identical.
This is a follow-up to #33434

Previous Attempt & Learning

#33434 helped identify that the issue wasn't with didFiberRender logic itself, but with when it was being called. The filtering behavior provided the key insight that components with identical Fiber objects shouldn't trigger render
detection when their parent HostComponents are filtered.

Example scenario:

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>
  );
};

Root Cause

The issue occurred because didFiberRender was being called for components whose Fiber objects remained referentially identical (prevFiber === nextFiber) but were nested under HostComponents. When the parent HostComponent processed its children during reconciliation, DevTools would check all child components without recognizing that some hadn't actually re-rendered.

Key insight

If prevFiber === nextFiber and the parent is a filtered HostComponent, then didFiberRender shouldn't be called at all - not because the function is wrong, but because the component genuinely hasn't re-rendered.

Solution

Instead of modifying didFiberRender logic, this fix prevents the function from being called when we can objectively determine a component hasn't re-rendered. The fix adds conditional checks in three critical locations:

  1. Profiler Data Collection (renderer.js:2816)
  • Prevents false positive entries in profiler commit data when components haven't actually re-rendered.
  1. Render Highlighting (renderer.js:3327)
  • Prevents incorrect highlighting of components during trace updates when they haven't changed.
  1. Inspector Cache Management (renderer.js:3359)
  • Preserves cached inspection data when components haven't actually re-rendered, avoiding unnecessary re-computation.

Implementation Details

The fix uses objective criteria to detect when didFiberRender shouldn't be called:

  if (
    prevFiber === nextFiber &&  // Same Fiber object reference
    nextFiber.return != null &&
    (nextFiber.return.tag === HostComponent || nextFiber.return.tag === HostSingleton)  // Parent is filtered HostComponent
  ) {
    // Don't call didFiberRender - component hasn't actually re-rendered
  }

This approach:

  • Addresses false positives at the source
  • Maintains existing didFiberRender logic unchanged
  • Applies consistently across all DevTools features
  • Uses objective, verifiable criteria
  • No performance impact on normal rendering

Related Issues

Fixes #33423, #19732

  - This commit addresses a bug in React DevTools where the profiler incorrectly reported user components as having re-rendered with the message "The parent component rendered," e
    ven when they had not. This typically occurred for sibling components (like  in the reported issue) nested under a  (e.g., ) when the parent re-rendered.

  - Problem: The  function, which determines if a component has rendered, was being called for components whose Fiber object remained referentially identical (). While  correctly
    checks for changes in , , and , the issue stemmed from the fact that it was invoked at all for these unchanged components, leading to misleading "render" indications in the profiler a
    nd highlight updates. The core problem was not the logic "within" , but rather the conditions under which it was "called".

  - Solution: To resolve this, a conditional check has been added within the  function, which is responsible for traversing and updating the Fiber tree. Before calling  for user components (Function, Class, Memo, ForwardRef components), the system now verifies two key conditions:
    1.  : The Fiber object itself has not changed (i.e., it's the same instance).
    2.   is a  or : The component's direct parent is a host element (like a ).
    If both conditions are met, it indicates that the component has not genuinely re-rendered, and  is explicitly set to . This prevents  from being called unnecessarily and avoids the false positive reporting in the DevTools profiler and render highlighting. The same logic is applied when checking if  has updated, ensuring consistency.

  - This change significantly improves the accuracy of the React DevTools profiler and render highlighting, providing developers with more reliable information about component re-renders and bailouts.

Fixes #33423
Relates to #33434
…er filtered HostComponents

  This commit addresses a bug in React DevTools where sibling user components were incorrectly reported as having re-rendered when they were nested under HostComponents (like <div>) that get filtered out by the DevTools component tree.

  ## Problem
  When a user component (e.g., Count) triggers a re-render within a HostComponent
  container, DevTools would incorrectly report sibling components (e.g., Greeting) as having re-rendered, even when their Fiber objects remained referentially
  identical (prevFiber === nextFiber). This created misleading information in:
    - Profiler data collection (false entries in commit data)
    - Render highlighting (incorrect visual indicators)
    - Inspector cache management (unnecessary invalidation)

  ## Root Cause
  The issue occurred because didFiberRender() was being called for components
  whose Fiber objects hadn't actually changed, but were children of HostComponents
  that were being processed during reconciliation. Since HostComponents are
  filtered out by default in DevTools, the relationship between unchanged sibling
  components wasn't being properly recognized.                                                                                                                                                                                                                                                     │

  ## Solution
  Instead of modifying the didFiberRender() function itself, this fix prevents
  the function from being called when we can determine that a component hasn't
  actually re-rendered. The key insight is that if:
    - prevFiber === nextFiber (same Fiber object reference)
    - nextFiber.return is a HostComponent or HostSingleton
  Then the component didn't actually re-render and didFiberRender() shouldn't be invoked.
@greptile-apps

greptile-apps Bot commented Dec 12, 2025

Copy link
Copy Markdown

Greptile Overview

Greptile Summary

Completes the fix for false positive render detection in React DevTools by adding the same conditional check to profiler data collection that was previously applied to render highlighting and inspector cache management.

  • Prevents didFiberRender() from being called when a component hasn't actually re-rendered (same Fiber reference with HostComponent/HostSingleton parent)
  • Applies consistent logic across all three DevTools features: profiler data collection (line 2816), render highlighting (line 3327), and inspector cache (line 3359)
  • Fixes false positives where sibling components under filtered HostComponents were incorrectly reported as re-rendered

Confidence Score: 5/5

  • Safe to merge - applies consistent, well-tested logic to complete the fix
  • This PR completes a fix that was partially implemented in commit c1cbc1e. The same conditional check is now applied consistently across all three locations where false positive render detection could occur. The logic is straightforward, matches the existing implementation pattern, and addresses a legitimate bug without introducing new complexity or side effects.
  • No files require special attention

Important Files Changed

File Analysis

Filename Score Overview
packages/react-devtools-shared/src/backend/fiber/renderer.js 5/5 Extends false positive fix to profiler data collection, completing coverage across all three DevTools features

@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 the Resolution: Stale Automatically closed due to inactivity label Feb 4, 2026
@everettbu

Copy link
Copy Markdown
Author

Upstream PR was closed or merged. Code is synced via branch mirror.

@everettbu everettbu closed this Feb 11, 2026
@everettbu
everettbu deleted the fix/devtools-profiler-render-highlight-3 branch February 11, 2026 17:36
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.

2 participants