SAP / spartacus

Spartacus is a lean, Angular-based JavaScript storefront for SAP Commerce Cloud that communicates exclusively through the Commerce REST API.
Apache License 2.0
739 stars 383 forks source link

perf: Improve rendering performance for large configuration models [CXSPA-7477] #18997

Closed Uli-Tiger closed 2 months ago

Uli-Tiger commented 3 months ago

Issue: The product configuration UI is completely re-rendered after each UI interaction. This may lead to performance issues for large configuration models, where a lot of attributes (>50) and/or a lot of possible values per attribute (>50) are rendered on the UI.

Solution: When this feature toggle(productConfigurationDeltaRendering) is activated, only these parts of the UI are re-rendered, that actually changed, significantly (up to factor 10) improving rendering performance for large models. Please note, this will influence how the pricing requests are processed and rendered. Instead of merging the prices into the configuration model, which effectively triggers re-rendering the whole UI-Component tree, the price supplements are kept in a separate subtree of the model, so that UI components can react independently on pricing chnages Hence, it is advised to do full regression testing after activation of this flag and before rolling this out to production.

Details: This optimization consists of 3 main parts: (1) A smart change detection for attributes implemented in configurator-attribute-composition.directive.ts. Basically, the directive will compare last rendered attribute state with the current attribute state and only trigger re-rendering of the attribute if the content of the attribute changed. Additionally, the ngFor generating the attribute list is enhanced with a trackBy function based on the attribute key. (2) The ngFor generating the group menu is enhanced with a trackBy function based on the group id. (3) Decouple pricing updates from configuration changes. Instead of merging pricing changes, which are fetched asynchronously, into the leaves (values) of the configuration tree within the configuration.reducer, the pricing changes are kept in a separate subtree configuration.priceSupplements. Unfortunately any attribute component and not only the pricing component should react on pricing changes. The attribute components build the ARIA labels for the attributes including any price related information (surcharges). To help attribute components to track pricing changes a new component service ConfiguratorDeltaRenderingService has been introduced. It monitors the configuration observable for pricing supplements fitting the given attribute key. Its rerender method will emit whenever a pricing change was detected. So the prices can now be updated independently from the rest of the configuration model. This is also a prerequisite for the optimization (1), as otherwise fetching the prices would always trigger re-rendering of all attributes.

Larisa-Staroverova commented 2 months ago

@Uli-Tiger, could you, please, verify, why build:libs is failing: image

Uli-Tiger commented 2 months ago

@Uli-Tiger, could you, please, verify, why build:libs is failing

this is fixed now.

Larisa-Staroverova commented 2 months ago

@Uli-Tiger, could you have a look at it? npm run build:libs is failing: image

Larisa-Staroverova commented 2 months ago

@Uli-Tiger, npm run build:libs is failing. Could you have a look at it? image

cypress[bot] commented 2 months ago



Test summary

119 0 2 0Flakiness 4


Run details

Project spartacus
Status Passed
Commit 64aa894314 ℹ️
Started Aug 1, 2024 1:54 PM
Ended Aug 1, 2024 1:57 PM
Duration 03:55 💡
OS Linux Ubuntu -
Browser Electron 118

View run in Cypress Cloud ➡️


Flakiness

regression/asm/asm.emulation.core-e2e.cy.ts Flakiness
1 Assisted Service Module > Customer Support Agent - Emulation > should checkout as customer (CXSPA-7026)
ssr/pages.core-e2e.cy.ts Flakiness
1 SSR > should render homepage
2 SSR > should render PLP
3 SSR > should render PDP

This comment has been generated by cypress-bot as a result of this project's GitHub integration settings. You can manage this integration in this project's settings in the Cypress Cloud

github-actions[bot] commented 2 months ago

Merge Checks Failed

Please push a commit to re-trigger the build. 
To push an empty commit you can use `git commit --allow-empty -m "Trigger Build"`
Larisa-Staroverova commented 2 months ago

@Uli-Tiger, npm run build:libs is failing. Could you have a look at it? image

github-actions[bot] commented 2 months ago

Merge Checks Failed

Please push a commit to re-trigger the build. 
To push an empty commit you can use `git commit --allow-empty -m "Trigger Build"`