Skip to content

perf: FIT-1302: Fix non-deterministic React keys causing unnecessary remounts#9268

Open
bmartel wants to merge 1 commit intodevelopfrom
fb-fit-1302
Open

perf: FIT-1302: Fix non-deterministic React keys causing unnecessary remounts#9268
bmartel wants to merge 1 commit intodevelopfrom
fb-fit-1302

Conversation

@bmartel
Copy link
Contributor

@bmartel bmartel commented Jan 26, 2026

Problem

Two critical anti-patterns in React key usage:

  1. guidGenerator() as key - Creates a new key on every render, forcing React to completely unmount and remount the component. Found in App.jsx for RelationsOverlay.

  2. Array index as key - Causes incorrect diffing when items are added, removed, or reordered. Found in multiple components.

Solution

Replace non-deterministic keys with stable identifiers:

File Before After
App.jsx key={guidGenerator()} key="relations-overlay"
Grid.jsx key={i} key={selected.id}
SidePanels.tsx key={i} key={Component.displayName}
OutlinerTree.tsx key={idx} key={tag.name}
PolygonRegion.jsx key={item.id || guidGenerator()} key={item.id}
TextAreaRegionView.jsx key={idx} key={\${item.id}-line-${idx}`}`

Files Changed

  • web/libs/editor/src/components/App/App.jsx
  • web/libs/editor/src/components/App/Grid.jsx
  • web/libs/editor/src/components/SidePanels/SidePanels.tsx
  • web/libs/editor/src/components/SidePanels/OutlinerPanel/OutlinerTree.tsx
  • web/libs/editor/src/regions/PolygonRegion.jsx
  • web/libs/editor/src/tags/control/TextArea/TextAreaRegionView.jsx

Replace non-deterministic and index-based keys with stable identifiers
to improve React reconciliation performance.

Critical fixes:
- App.jsx: Replace guidGenerator() with stable 'relations-overlay' key
  (was causing RelationsOverlay to remount on every parent render)
- PolygonRegion.jsx: Remove guidGenerator() fallback, use item.id only

High-frequency component fixes:
- SidePanels.tsx: Use Component.displayName/name instead of index
- OutlinerTree.tsx: Use tag.name or tag.type instead of index
- Grid.jsx: Use selected.id instead of loop index
- TextAreaRegionView.jsx: Use item.id with line index for stability

Using array index as key causes React to incorrectly diff when items
are added, removed, or reordered. Using guidGenerator() creates a new
key every render, forcing complete remount of the component tree.
@codecov
Copy link

codecov bot commented Jan 26, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 57.91%. Comparing base (609d271) to head (18f260d).
⚠️ Report is 8 commits behind head on develop.

❗ There is a different number of reports uploaded between BASE (609d271) and HEAD (18f260d). Click for more details.

HEAD has 1 upload less than BASE
Flag BASE (609d271) HEAD (18f260d)
pytests 1 0
Additional details and impacted files
@@             Coverage Diff             @@
##           develop    #9268      +/-   ##
===========================================
- Coverage    66.82%   57.91%   -8.92%     
===========================================
  Files          830      561     -269     
  Lines        64879    40547   -24332     
  Branches     10971    11008      +37     
===========================================
- Hits         43355    23481   -19874     
+ Misses       21520    17062    -4458     
  Partials         4        4              
Flag Coverage Δ
lsf-e2e 52.37% <100.00%> (+0.38%) ⬆️
lsf-integration 48.21% <0.00%> (-0.07%) ⬇️
lsf-unit 8.86% <0.00%> (-0.02%) ⬇️
pytests ?

Flags with carried forward coverage won't be shown. Click here to find out more.

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

🚀 New features to boost your workflow:
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@netlify
Copy link

netlify bot commented Jan 26, 2026

Deploy Preview for heartex-docs canceled.

Name Link
🔨 Latest commit 18f260d
🔍 Latest deploy log https://app.netlify.com/projects/heartex-docs/deploys/6977b041aeb29f00081c9fa9

@netlify
Copy link

netlify bot commented Jan 26, 2026

Deploy Preview for label-studio-docs-new-theme canceled.

Name Link
🔨 Latest commit 18f260d
🔍 Latest deploy log https://app.netlify.com/projects/label-studio-docs-new-theme/deploys/6977b0417ddc0c0008958334

@netlify
Copy link

netlify bot commented Jan 26, 2026

Deploy Preview for label-studio-storybook ready!

Name Link
🔨 Latest commit 18f260d
🔍 Latest deploy log https://app.netlify.com/projects/label-studio-storybook/deploys/6977b0415b73530008a02c31
😎 Deploy Preview https://deploy-preview-9268--label-studio-storybook.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@netlify
Copy link

netlify bot commented Jan 26, 2026

Deploy Preview for label-studio-playground ready!

Name Link
🔨 Latest commit 18f260d
🔍 Latest deploy log https://app.netlify.com/projects/label-studio-playground/deploys/6977b041f1bd000008efe622
😎 Deploy Preview https://deploy-preview-9268--label-studio-playground.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

Comments