Fork me on GitHub

Is there a way to log/debug/visualize which subscriptions are re-calculated in response to an event? I want to optimize this part of an app in hope for better performance.


@mbertheau someone correct me if I'm wrong but AFAIK there's no easy way of doing this right now because subscription dependencies are implicit, they are linked together by calling subscribe inside the signal function of a reg-sub so re-frame is actually not aware of this connection.


Same thing with views, they call subscribe directly so there's no easy way of querying who's subscribed to what.


@mbertheau two ways: 1. there is an alpha tracing capability built into re-frame. It has no docs. But it will tell you everything that happens. It will be getting more love soon. 2. this idea:


For the tracing approach, note that it will slow down your app significantly and it only works in Chrome and Safari because of custom formatters.


@mikethompson Can you give me a hint or a link to a line in the source about how to use/enable the tracing capability? I saw that in the release notes as well and went looking for it, but I couldn't find it. I'll look into re-frame-trace, that looks interesting.


Warning: you are using alpha quality software. Still largely experimental. Have I been scary enough?


@danielcompton @danieleneal made a gist with code related to our earlier discussion on the file uploading component 👉


@mikethompson Absolutely! Thanks 🙂


Hello. What is a recommended way of using subscription results in event handler? According to [this]( it's a bad idea but how would i overcome it? Just call underlying sub method from event handler? I suppose calling subs/cache-lookup or smth like this would be a bad idea?


@nidu I keep the functions that subscriptions call around and call them in an event handler


@mbertheau yeah, that seems right to me. Just wanted to use computed subscription value to avoid unneeded computation. Not that it affects performance but it probably would be nice


I agree. This is an unsolved problem in re-frame afaik.


It’s more an issue of understanding. A subscription does not return a value, it returns a signal of ever changing values, so while you may think you want the result of a subscription in an event handler you actually don’t because an event handler can’t react to the changes to the signal. Since you actually just want a value @mbertheau ‘s way is the right way. You put the shared computation in a function and you provide a changing over time signal via a subscription and a straight value via the function itself.


I think this part is clear. The concern is with the double calculation. The subscription has the result of the computation already, and it's a valid use case to want to access this result in an event handler.


Fair, but be aware that subscriptions will recalculate every requestAnimationFrame anytime it’s input’s change which if you are using the basic form will be everytime the app-db changes … so one more computation in that constantly reoccuring computation engine isn’t too big of a deal


Maybe put required subscription results in event arguments? Technically i need subscription value at the moment when event was emited because that's the state of the world when it was called, not when it's handled because that possibly may mismatch.


That's valid as well


@mbertheau That r-sub is nice! Any thoughts on solving the “pure function” issue by allowing the macro to take a symbol which when present will bind the computation function to that symbol?


So you don’t even have to separate the pure function and the registration, the macro will give you that pure function.



(r-sub char-result-group :char-result-group [i] [char-results [:char-results]]
       (get char-results i))
would expand to
  (defn char-result-group [[char-results] [_ i] _] (get char-results i))
  (fn [[_ i] _] [(re-frame.core/subscribe [:char-results])])


@kasuko You would prefer the pure function so have a such strangely structured argument vector?


Apart from the argument vector, the macro I used before r-sub did exactly what you proposed. Given the simple alternative:

(defn char-result-group [i char-results] (get char-results i))
(r-sub :char-result-group [i] [char-results [:char-results]]
, I think auto-defining the function is too much implicit magic.