Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor: app config and header component signals #2427

Merged
merged 5 commits into from
Nov 15, 2024

Conversation

chrismclarke
Copy link
Member

@chrismclarke chrismclarke commented Sep 18, 2024

PR Checklist

  • PR title descriptive (can be used in release notes)

TODO

Description

Following recent improvements to app config handling, update the main app.component.ts and app.header.ts to make use of signals, computes and effects. These should be generally more performant and simplify some of the more complex usage patterns (e.g. rxjs observable subscriptions)

Review Notes

See demo below triggering skin change which should also trigger knock-ons to theme, header and footer config. These appeared to all be working as expected when testing locally, but would be good to verify

Screenity.video.-.Sep.18.2024.webm

Dev Notes

I've started just refactoring these components as they are the most visible in the app and so should have the most immediate benefit/impact. There's around 10-15 additional services which call the appConfigService and could potentially be refactored, although most of these are less related to UI (but would still likely benefit from more fine-grained update handling).

It's hard to measure the exact performance improvements, although see benchmarks from angular profiler below. These are skewed however as angular change detection runs more greedily in development mode than production anyways, but should still give some indication

Git Issues

Closes #

Screenshots/Videos

Before
Using angular devtools profiler, can see while switching skins a huge number of change detection cycles triggered
image

After
Minimal detection cycles triggered
image

@github-actions github-actions bot added the maintenance Core updates, refactoring and code quality improvements label Sep 18, 2024
@github-actions github-actions bot added the scripts Work on backend scripts and devops label Sep 18, 2024
@chrismclarke chrismclarke marked this pull request as ready for review November 15, 2024 00:12
@github-actions github-actions bot added maintenance Core updates, refactoring and code quality improvements and removed maintenance Core updates, refactoring and code quality improvements labels Nov 15, 2024
@chrismclarke
Copy link
Member Author

@jfmcquade
Apologies this PR was left in draft waiting for #2423 but I forgot to mark as ready for review. I think it should be now, hopefully it should work alongside other changes you're planning on implementing for header/footer changes.

Copy link
Collaborator

@jfmcquade jfmcquade left a comment

Choose a reason for hiding this comment

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

Thanks, @chrismclarke. Nice improvements to have ahead of implementing template-level header and footer customisation.

Everything seem to be working as expected from my functional testing. And nice to see evidence of the improved change detection handling, even if the actual performance gains are hard to quantify.

this.setHeaderCollapse(collapse);
}
},
{ allowSignalWrites: true }
Copy link
Collaborator

Choose a reason for hiding this comment

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

This pattern makes sense to me, and we've already introduced similar effects in other components. But I note that the Angular docs discourage using effects in general, and further suggest that allowSignalWrites can be enabled if "absolutely necessary".

Do you have an idea of what a more Angular-y structure would be? It seems obvious to me that effects are useful and that we might want to set signals inside them

Copy link
Member Author

@chrismclarke chrismclarke Nov 15, 2024

Choose a reason for hiding this comment

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

My rough take on it is given how easy it is to accidentally end up in infinite loops it makes sense to be cautious about using allowSignalWrites, and intentional when using to set signals. Pretty much any time you use there could be an alternate pattern available using computed signals instead (usually with additional intermediate variables), or by using regular variables and cdr methods to prompt change detection.

I.e. in this example the signal write is so that the marginTop can be set following changes and automatically detected. If we just had a regular marginTop variable that is set as part of the effect (instead of a signal) we could update and then call cdr.markForCheck. I don't like this pattern as much as using both signals and cdr feels a bit wrong given they're meant to address the same problem

Alternatively you could make both headerHeight and headerCollapse computed properties that depend on headerConfig, and marginTop a third computed property that depends on the other two. Again, I'm not a huge fan of this pattern - what you save in reactivity chain you lose by having two separate computed functions that duplicate some amount of code between and lose visibility on the relation between them. But all this is quite subjective, and I can see why angular struggles to give clear guidance of when/when not to use

@jfmcquade jfmcquade merged commit 9a8e165 into master Nov 15, 2024
7 checks passed
@jfmcquade jfmcquade deleted the refactor/app-config-signals branch November 15, 2024 11:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
maintenance Core updates, refactoring and code quality improvements scripts Work on backend scripts and devops
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants