Skip to content

⚡ Bolt: Make CartSummary a data class to prevent unnecessary recompositions#83

Open
himattm wants to merge 1 commit into
mainfrom
bolt-cart-summary-data-class-1562027274511002186
Open

⚡ Bolt: Make CartSummary a data class to prevent unnecessary recompositions#83
himattm wants to merge 1 commit into
mainfrom
bolt-cart-summary-data-class-1562027274511002186

Conversation

@himattm
Copy link
Copy Markdown
Owner

@himattm himattm commented May 7, 2026

💡 What: Changed CartSummary from a regular class to a data class.

🎯 Why: Regular classes in Kotlin are compared by reference. When ProductListScreen recomposed (e.g. from an unrelated refresh count change), a new CartSummary instance was created. Compose saw a new reference and unnecessarily recomposed CartBanner, even when the cart items and total price were identical. By making it a data class, Compose can compare the contents structurally.

📊 Impact: Reduces CartBanner recompositions. Wasted recompositions on unrelated parent state changes (like refreshing) drop to 0, bounding recompositions tightly to 1:1 with actual cart content updates.

🔬 Measurement: demo/src/androidTest/java/demo/app/RecompositionRegressionTest.kt was updated to assert the fixed expected behavior (assertStable() instead of atLeast = 1 for refresh actions, exactly 2 instead of at least 3 for combined operations).


PR created automatically by Jules for task 1562027274511002186 started by @himattm

Changed CartSummary to be a data class to prevent Jetpack Compose from performing unnecessary recompositions on the CartBanner due to identity equality checks. Tests updated to reflect correct behavior.

Co-authored-by: himattm <6266621+himattm@users.noreply.github.com>
@google-labs-jules
Copy link
Copy Markdown

👋 Jules, reporting for duty! I'm here to lend a hand with this pull request.

When you start a review, I'll add a 👀 emoji to each comment to let you know I've read it. I'll focus on feedback directed at me and will do my best to stay out of conversations between you and other bots or reviewers to keep the noise down.

I'll push a commit with your requested changes shortly after. Please note there might be a delay between these steps, but rest assured I'm on the job!

For more direct control, you can switch me to Reactive Mode. When this mode is on, I will only act on comments where you specifically mention me with @jules. You can find this option in the Pull Request section of your global Jules UI settings. You can always switch back!

New to Jules? Learn more at jules.google/docs.


For security, I will only act on instructions from the user who triggered this task.

Copy link
Copy Markdown

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request converts the CartSummary class to a data class to ensure structural equality, which prevents unnecessary recompositions in Jetpack Compose. Additionally, the RecompositionRegressionTest has been updated to assert stable behavior and specific recomposition counts. The review feedback points out several locations where existing code comments have become stale or inaccurate as a result of these changes and recommends updating or removing them to maintain documentation accuracy.

// causing recomposition even when the logical content is the same.
// Making this a `data class` would fix the problem.
class CartSummary(val itemCount: Int, val totalPrice: String)
data class CartSummary(val itemCount: Int, val totalPrice: String)
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

The comments on lines 46-48 (and the detailed explanation in the file header at lines 35-44) are now outdated. They describe CartSummary as an unstable class and suggest converting it to a data class, which has now been done. These comments should be removed or updated to reflect the current state of the code.


// ISSUE: CartBanner recomposes despite no logical change to the cart
composeTestRule.onNodeWithTag("cart_banner").assertRecompositions(atLeast = 1)
composeTestRule.onNodeWithTag("cart_banner").assertStable()
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

The surrounding comments (line 118 and lines 121-124) are now stale. They describe a recomposition issue and suggest a fix that has already been applied in this line. Additionally, the comment on line 124 mentions assertFirstComposition(), which differs from the actual implementation assertStable(). These comments should be cleaned up.

// recompositions (2 from selects + 3 from refreshes).
// Budget: at most 5 -- bounded at 1:1 with parent recompositions.
composeTestRule.onNodeWithTag("cart_banner").assertRecompositions(atMost = 5)
composeTestRule.onNodeWithTag("cart_banner").assertRecompositions(exactly = 2)
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

The comments on lines 162-165 and 168-170 are now outdated. They refer to the "current behavior" as an issue and describe the data class fix as a future step. Since the fix is now implemented, these comments should be updated or removed.

// FIX: With `data class CartSummary`, only the 2 selects would cause
// recomposition. The fixed assertion would be: assertRecomposesExactly(2)
composeTestRule.onNodeWithTag("cart_banner").assertRecompositions(atLeast = 3)
composeTestRule.onNodeWithTag("cart_banner").assertRecompositions(exactly = 2)
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

The comments on lines 200-203 are now stale as they describe the recomposition issue that this PR resolves. They should be removed or updated to match the current stable behavior.

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.

1 participant