Fork me on GitHub
#cljfx
<
2022-10-24
>
skynet14:10:35

is there a way to make the context cache evict some entries after a different threshold than others? for example, if I have a subscription that might be some megabytes, I might only want 1 or 2 cached versions of it, but I want to allow a large number of other things which are probably small this might be more of a general clojure core.cache question. I could probably come up with something that works like this, but I'm wondering if someone's already done it? or maybe there are better ways to deal with it

vlaaad15:10:19

I would suggest trying not using contexts at all. I know this is something that is advertised in the cljfx readme, and it makes some stuff easy to do, but I never really needed this stuff in any cljfx app I did. Just use atom as a top-level state, and mount a rendered onto the atom, and make the data flow from the root view to the leaves. Default cljfx component management has a built-in “cache” of latest input values which is enough in 100% of the cases.

vlaaad15:10:12

So in my experience “Subscriptions and contexts” and “Event handling on steroids” sections from the readme turned out to be unnecessary complexity, and the best map event handler is #(swap! state-atom (:fn %) %) , where listener descriptions are {:fn #'on-some-event}

skynet15:10:04

what about the use of sub-ctx for data processing done in components that could be slow?

vlaaad16:10:25

What's the average time spent on this slow data processing?

vlaaad16:10:26

I'd say in general some slow stuff like collection search + sorting can easily happen inside function components, maybe up to 50ms, if it's above then it makes sense to make sure the slow stuff is explicit, e.g. launch a future in the event handler, and when the results are ready, put them into the state atom

skynet16:10:53

I notice lag issues in my app with typing when some components use even 1ms to process data like sorting. I think it's death by a thousand cuts type thing, if there are enough components processing data while rendering, and you type in a text box, it will cause noticeable lag

vlaaad16:10:43

Have you profiled your app to see the bottleneck?

vlaaad16:10:08

1ms is 1/16th of a frame, shouldn't be too slow to cause such lagging unless it happens multiple times per update...

skynet16:10:54

yep I use tufte and track each component, when typing in a text box, I may see something like this

pId                                       nCalls        Min      50% ≤      90% ≤      95% ≤      99% ≤        Max       Mean   MAD      Clock  Total

component1                                   533    13.69μs    94.15μs   665.66μs   694.50μs   783.55μs     1.15ms   330.62μs  ±90%   176.22ms    19%
component2                                   318   427.71μs   493.01μs   546.93μs   574.72μs   665.59μs   898.86μs   502.43μs   ±6%   159.77ms    17%
component3                                   56     2.40ms     2.50ms     2.64ms     2.80ms     2.95ms     3.07ms     2.54ms   ±3%   142.06ms    15%
so even if the component calls are fast, with enough of them happening it causes the issue. putting data manipulation in sub-ctx is how I've been fixing it now that it's become an issue

vlaaad16:10:17

I would suggest trying clj-async-profiler instead: https://github.com/clojure-goes-fast/clj-async-profiler/ i.e. start the profiler for 10 seconds with (clj-async-profiler.core/profile-for 10) , then switch to the app and type in the text input that triggers lagging, then have a look at where most of the time is spent

👍 1
skynet16:10:42

I'll check that out, thanks!

skynet17:10:53

https://clojurians.slack.com/archives/CGHHJNENB/p1666628468768669?thread_ts=1666623515.779399&amp;cid=CGHHJNENB the problem is, I have a few of these in various components, so they add together. is there an alternative to sub-ctx that you would use in an app like that?