perf(core): memoize context provider values to prevent cascading re-renders#3366
Open
orrgottlieb wants to merge 2 commits into
Open
perf(core): memoize context provider values to prevent cascading re-renders#3366orrgottlieb wants to merge 2 commits into
orrgottlieb wants to merge 2 commits into
Conversation
Wraps unmemoized `value` props on `LayerProvider`, `Heading`'s `TypographyContext`, `AlertBannerContext`, `GridKeyboardNavigationContext`, `ListContext`, `TableContainerProvider`, and `RelatedComponentsContext` in `useMemo` (or hoists to a module-scoped frozen constant where the value never depends on render-time state). When a Provider receives a fresh object literal each render, every consumer of that context re-renders even when nothing in the value actually changed. For widely-used providers like Layer and Table, that cascade hits every nested element on every parent update. Audit finding #15.
Contributor
Code Review by Qodo🐞 Bugs (0) 📘 Rule violations (0) 📎 Requirement gaps (0)
Great, no issues found!Qodo reviewed your code and found no material issues that require reviewPrevious review resultsReview updated until commit 46800f0 Results up to commit da05ec9
Great, no issues found!Qodo reviewed your code and found no material issues that require review |
Wrapping the context value in useMemo widened textColor's inferred type to string, breaking AlertBannerContextType assignability. Annotate the useMemo with the explicit context type so the literal union is preserved. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Contributor
|
Persistent review updated to latest commit 46800f0 |
Contributor
|
📦 Bundle Size Analysis ✅ No bundle size changes detected. Unchanged Components
📊 Summary:
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
User description
Summary
Stabilizes
valuereferences on the following Context providers so that consumers stop re-rendering when the value object is structurally identical:LayerProvider(packages/components/layer)Heading→TypographyContext(packages/components/typography) — hoisted to module-scope constantAlertBannerContext(packages/core)GridKeyboardNavigationContext(packages/core)ListContext(packages/core)TableContainerProvider(packages/core)RelatedComponentsContext(packages/storybook-blocks)Why
From a performance audit (item #15): when a Provider receives a fresh object literal each render (
value={{ foo, bar }}), every consumer of the context re-renders — even when nothing in the value actually changed. For widely-used providers like Layer and Table, that cascade hits every nested element on every parent update.Test plan
🤖 Generated with Claude Code
PR Type
Enhancement
Description
Memoize context provider values to prevent cascading re-renders
valueprops inuseMemoor hoists to module-scoped constantsFix AlertBannerContextType preservation after memoization
Diagram Walkthrough
File Walkthrough
AlertBannerContext.ts
Export AlertBannerContextType for type safetypackages/core/src/components/AlertBanner/AlertBannerContext.ts
AlertBannerContextTypeto allow type annotation in AlertBannercomponent
useMemoAlertBanner.tsx
Memoize AlertBanner context value with type annotationpackages/core/src/components/AlertBanner/AlertBanner.tsx
AlertBannerContextTypefrom AlertBannerContextuseMemowith explicit type annotation topreserve textColor union literal
GridKeyboardNavigationContext.ts
Memoize GridKeyboardNavigation context return valuepackages/core/src/components/GridKeyboardNavigationContext/GridKeyboardNavigationContext.ts
useMemoto stabilize context object referenceonOutboundNavigationdependencyList.tsx
Memoize List context value to prevent re-renderspackages/core/src/components/List/List.tsx
listContextValuevariable withuseMemoto stabilize contextreference
updateFocusedItemdependencyTableContainer.tsx
Memoize TableContainer context valuepackages/core/src/components/Table/TableContainer/TableContainer.tsx
useMemohooktableContainerContextValuewithuseMemoto stabilize contextreference
menuContainerRefis created once percomponent instance
LayerProvider.tsx
Memoize LayerProvider context valuepackages/components/layer/src/LayerProvider/LayerProvider.tsx
useMemohookvaluevariable withuseMemoto stabilize context referencelayerRefdependencyHeading.tsx
Hoist Heading TypographyContext value to constantpackages/components/typography/src/Heading/Heading.tsx
HEADING_TYPOGRAPHY_CONTEXT_VALUEforTypographyContext value
TypographyContext.Provider
related-components.tsx
Memoize RelatedComponents context valuepackages/storybook-blocks/src/components/related-components/related-components.tsx
relatedComponentsContextValuewithuseMemoto stabilize contextreference
linkTargetdependency