Fork me on GitHub
#reagent
<
2021-12-16
>
frankitox14:12:31

There's any way to check execution times in Reagent? I'm interested in how much it takes to render a component and https://github.com/day8/re-frame/blob/master/docs/Performance-Problems.md#using--on-big-structures`=`. I'm using re-frame trace capabilities to see how long it takes to run a subscription, but I don't think that includes the comparison time, right? :thinking_face: If I record how long it takes to render a component, will that include the comparison time? I'm guessing no

frankitox14:12:48

BTW, I'm using react native

Roman Liutikov14:12:26

is there DevTools for RN to record performance profile?

Roman Liutikov14:12:45

Chrome's DevTools are really good at this

frankitox14:12:36

There's the debug mode, that (I'm not completely sure) runs the code in the computer so it runs way faster. But maybe profiling there can be helpful? BTW, you mean the Performance tab right?

Roman Liutikov14:12:01

yeah, on the web you'd record a profile and then search a function of interest by name, it will show you aggregate execution time of the function in a selected part of the flame chart

frankitox15:12:40

well, that really helps! I hope there's at least a bit of consistency between the running times in the phone and the computer

frankitox15:12:54

but thank you 😁

lilactown15:12:06

notably > Another way to profile JavaScript is to use the Chrome profiler while debugging. This won't give you accurate results as the code is running in Chrome but will give you a general idea of where bottlenecks might be.

lilactown15:12:44

I really like chrome's profiler (having spent hours in it at this point lol) and it may give you a starting point, but may not give you realistic perf info

frankitox16:12:02

Yes, it looks most of the work is the subscription, which was unexpected to me. Still would be nice to understand the reagent part of the trace

frankitox16:12:21

Also I'm regretting that many unnamed anonymous fns in my code :man-facepalming:

yes 1
B Treebeard16:12:11

(defn child-component []
  (fn []
    [:div (rand-int 1000)]))

(defn parent-component []
  (let [dummy-fn (constantly 42)
        dom-ref (rc/atom nil)
        ref-fn #(reset! dom-ref %)]
    (fn []
      [:<>
       [child-component
        {:dummy-fn #_dummy-fn (constantly 42)
         :dummy-ref @dom-ref}]
       [:div {:ref #_ref-fn #(reset! dom-ref %)}
        (rand-int 1000)]])))

(rd/render [parent-component]
           (. js/document (getElementById "app")))
Hi folks, what is it with my snippet that causes child-component to constantly re-render? When I make the :ref callback inline for parent-component, I can see why this would cause the parent-component to constantly re-render. But when I also make the :dummy-fn callback inline, I see the child-component constantly re-renders. Why does this happen, when the dummy-fn prop/argument isn't a part of the child-component definition (either in the outer or inner functions of the Form-2 component)?

p-himik16:12:23

Evaluate this in your REPL: (= (constantly 42) (constantly 42)).

p-himik16:12:43

Regardless of whether :dummy-fn is used or not, it will be passed as a property. It's different, so the component will be re-rendered.

B Treebeard16:12:29

Right, I wasn't relying on (= (constantly 42) (constantly 42)) to be true. I was just surprised that :dummy-fn is treated as a prop. This doesn't sync up in my head with the "Rookie mistake" described https://github.com/reagent-project/reagent/blob/master/doc/CreatingReagentComponents.md#form-2--a-function-returning-a-function.

p-himik16:12:04

The inner render function of child-component will be called regardless of whether the arguments are used. It's just that if you forget to repeat the arguments like described in the "Rookie mistake" section there, the old values will be used. It will lead to the new Hiccup vector being = to the old one, thus leading to no re-rendering. E.g. with this simple code:

(defn c [a]
  (js/console.log "c a outer" a)
  (fn []
    (js/console.log "c a inner" a)
    [:span "A" a]))

(defn app []
  (r/with-let [a (r/atom 1)]
    [:div
     [:button {:on-click #(swap! a inc)}
      "inc!"]
     [c @a]]))
you can confirm that the outer fn is called exactly once and the inner one is called one time initially plus once every time you press the button - even though it doesn't use the new a value.

💯 1
B Treebeard17:12:18

Got it, that makes perfect sense. I had similar console.log statements, and I was conflating the repeated logging with re-rendering. But I get now that repeated calls of the inner function don't lead to re-rendering if the Hiccup is unchanged. Thanks for helping me see this!

👍 1