re-frame

tatut 2025-09-09T05:35:30.463549Z

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?

Kimo 2025-09-09T07:14:02.443269Z

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.

Kimo 2025-09-09T07:16:24.637699Z

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

caleb.macdonaldblack 2025-09-09T07:55:55.580029Z

you might be able to do something with reg-sub-raw

👍 1
caleb.macdonaldblack 2025-09-09T07:57:03.732819Z

Maybe watch a sub, batch process to enrich and then give the result back

tatut 2025-09-09T08:11:46.108679Z

thanks, I'll try that

Kimo 2025-09-09T08:43:28.756149Z

Some docs for re-frame alpha - soon to be released 😉

Kimo 2025-09-09T08:45:00.096669Z

Kimo 2025-09-09T08:46:12.568219Z

Kimo 2025-09-09T08:48:36.224399Z

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}}}}}

tatut 2025-09-09T09:27:47.386599Z

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

tatut 2025-09-09T09:28:03.082659Z

changed the initial subscription to just get the data from app db without any calculations

tatut 2025-09-09T09:28:19.307249Z

this seems to work and has no warnings

tatut 2025-09-09T06:00:22.448709Z

I'm using the inject cofx as per https://day8.github.io/re-frame/FAQs/UseASubscriptionInAnEventHandler/#re-frame-utils idk if that's "safe"

caleb.macdonaldblack 2025-09-09T06:09:03.402919Z

I wouldn’t recommend using subscriptions in your events, even through inject-cofx

caleb.macdonaldblack 2025-09-09T06:09:18.878989Z

Take a look at flows: https://day8.github.io/re-frame/Flows/

caleb.macdonaldblack 2025-09-09T06:09:50.620619Z

> 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.

caleb.macdonaldblack 2025-09-09T06:10:10.677659Z

> On every event, when the values at :inputs change, :output is run, and the result is stored in app-db at :path.

caleb.macdonaldblack 2025-09-09T06:22:10.328969Z

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

tatut 2025-09-09T06:22:23.607529Z

I'm probably in for a large refactoring in any case

caleb.macdonaldblack 2025-09-09T06:34:39.104039Z

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).

tatut 2025-09-09T06:36:00.604189Z

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

caleb.macdonaldblack 2025-09-09T06:38:45.734819Z

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