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

Core/React Question: Data Layer Re-renedering #543

Open
KieranTH opened this issue Nov 12, 2024 · 2 comments
Open

Core/React Question: Data Layer Re-renedering #543

KieranTH opened this issue Nov 12, 2024 · 2 comments
Labels
enhancement New feature or request

Comments

@KieranTH
Copy link

Hey people!

I have quite a general question surrounding the Data Layer model for Player.

As I've been using Player quite extensively for the past 9-10 months or so, I have to say it's an incredibly impressive feat for server driven UI!

One thing I'd like to understand more is the data layer for a Player instance. So based on previous discussion I know there's an AST involved that essentially parses out all expressions and binding instances, being {{...}} and @[...]@.

So... after trailing a bit of time trying to navigate through the source code, I thought I may as well ask - How is the actual data objects stored for a Player instance? Is the data layer essentially hoisted at the top of the Player instance and used as a store? Or does it utilise context (on the React side), to make all data paths accessible to the AST when parsing bindings.

The only reason I'm asking is purely due to a potential suggestion - Where currently I tend to have alot of re-renders when using heavily nested assets, which tends to be quite common with complex UI. I know a big culprit for excessive re-renders is the usage of Context, because Context will essentially always force a full re-render of children on any changes.

Depending on how the current model works, my only suggestion was going to be something along the lines of using a Player Instance wide "store" to deal with persistent storage. Zustand is a great example of a "global" store that has a great feature of Transient Updates, meaning the React components under the hood don't re-render unnecessarily, because the components have to subscribe the data changes. (I know the data layer for Player is above any React implementations, I'm just mentioning Zustand because it's a good example of eliminating performance issues with React).

I know this may not be completely applicable to the Player system, but I thought it may be worth a shot just shooting by my thoughts.

If anyone has any additional suggestions for mitigating excessive re-renders, that'd be amazing!

React state management is quite funky, and when UIs get complex, they always tend to leave performance on the table!

Cheers!

@KieranTH KieranTH added the enhancement New feature or request label Nov 12, 2024
@KetanReddy
Copy link
Member

For some background: Currently, the base data store that Player ships with in an in memory model that is contained in Core Player. In most cases those data operations (like resolving templates/expressions in content) should be performed in Player Core so by the time the AST is handed off from Core to the platform, the content is ready to be rendered. Most of the interactions with the data model at the asset level should be set calls when data needs to be set and any get calls should really be done in a transform.

As for its impact on view updates and re-rendering. When Player Core produces its AST for a platform Player to render it does produce the whole tree again and leave it up to the platform to choose how to render it. You are correct though that for React this does mean each component backed asset gets its props again but only the asset(s) that were impacted by the view update should get new props and need to re-render. The benefit of this though is the actual view update calculation is deferred to Player. For logic heavy screens with very intertwined data, having each asset instance have to know about what data influences how it should render would lead to the re-implementation of a lot of logic across platforms.

We haven't seen a ton of performance issue with heavily nested content but I guess that relative. Can you give us an idea on how nested the content you're using is? The only other suggestion I would have is to maybe re-evaluate where the asset boundaries are? It might be better to combine multiple UI elements into a single asset (or break a bigger one up into smaller assets) depending on how your data will look.

@KieranTH
Copy link
Author

KieranTH commented Dec 2, 2024

Hey!

Appreciate the in depth reply!

All of that makes complete sense. I can see that hooking assets into their dependencies would be a bit restrictive so that's fair enough.

In terms of the re-rendering, I guess thats a symptom of the implementation I'm using. Alot of the logic around the screens/views I tend to use are around this particular flow:

  1. View loads.
  2. View looks for X search params in URL.
  3. View (an asset in the View) queries for data given X argument.
  4. That data is set into the in-memory data for that player instance.
  5. Numerous assets are then attached to that in-memory data.

So my main concern was that if the in-memory store was updating, and Asset-A was looking at path data.1 would updating data.2 cause Asset-A to re-render but I think per your explanation, that seems to be covered by the props that the React component ingests, which makes sense. I guess my assumption was that because the in-memory was platform agnostic, I was worried that React would just go "oh the store object changed, I need to re-render" but per your explanation, I guess React doesn't really know the store itself changed, only the path'd data from in-memory. So that's nice to hear!

Thanks again for the explanation, I appreciate your time

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants