I have a subscription that enriches some data from the server, and uses lots of other subs to do it... and that is getting slow for customers (like "unresponsive script" levels of slow). I tried moving that to chained events that batch process it, but injecting the subs gets me "outside reactive context" warnings. Is there some other trick to try?
Calling subscribe within an event handler can be okay. If you use re-frame.alpha, the default behavior of a subscription is memory-safe (even outside of "reactive context"). That might not fix your performance issues, but it would be feasible. From there, you could try changing the lifecycle of each subscription.
As caleb mentions, flows can achieve a similar thing, but that tends to involve more refactoring. re-frame.alpha , however, works as a drop-in replacement for re-frame.core
you might be able to do something with reg-sub-raw
Maybe watch a sub, batch process to enrich and then give the result back
thanks, I'll try that
Some docs for re-frame alpha - soon to be released đ
A nice way to use re-frame.alpha is with an ns-alias. For example, if you use shadow-cljs:
;; shadow-cljs.edn
{...
:builds {:app {:build-options {:ns-aliases {re-frame.core re-frame.alpha}}}}}I did a (defonce enrichment-process (reagent.ratom/run! ...code to deref all subscriptions and start a setTimeout batch process...)) then at the last batch, it dispatches an event to set the enriched data to the app db
changed the initial subscription to just get the data from app db without any calculations
this seems to work and has no warnings
I'm using the inject cofx as per https://day8.github.io/re-frame/FAQs/UseASubscriptionInAnEventHandler/#re-frame-utils idk if that's "safe"
I wouldnât recommend using subscriptions in your events, even through inject-cofx
Take a look at flows: https://day8.github.io/re-frame/Flows/
> A flow describes how to derive a value from other values.
> When one part of your app state changes, another part changes in response.
> More concretely, when the values change at one or more paths within app-db, then the value at another path is âautomaticallyâ recalculated.
> On every event, when the values at :inputs change, :output is run, and the result is stored in app-db at :path.
Another thing you could do move the logic out of your subscriptions and into your events and delete the subscription code youâre not using anymore
I'm probably in for a large refactoring in any case
Also consider https://www.martinfowler.com/bliki/CommandQuerySeparation.html when designing your events and subscriptions. I suggest keeping them seperate from one another (not calling subs in your events).
this is an old app, I was hoping I wouldn't have to do major structural changes to optimize it, but I guess it's unavoidable
Fair enough. You might be able to keep using you subscriptions by using some low-level re-frame code where youâre having performance problems. Iâm putting something together for you now. Just give a sec