cljs-react-perf icon indicating copy to clipboard operation
cljs-react-perf copied to clipboard

What's the ideal way to invoke renders?

Open lynaghk opened this issue 8 years ago • 1 comments

Consider a UI is derived entirely from a single state atom, where all updates go through the same codepath.

(def !state 
  (atom {}))

(rum/defc *app [app-state] ...)

(defn trigger! 
  [event]

  ;;update the application state
  (swap! !state update-state-fn event)

  ;;re-render the application state
  (.render js/ReactDOM 
           (*app trigger! @!state) 
           (.getElementById js/document "my-app")))

(trigger! :first-event-to-start-app)

One benefit of this rendering approach is that there is no distinction between the initial render and subsequent renders. No need to keep track of a React component, add watches to the state atom, or anything like that.

One downside is that if trigger! is called multiple times within a single frame, the React render function will run needlessly multiple times, when it really only needs to run once on the latest application state for a given frame.

Would it be better to do use requestAnimationFrame or mount the component once and then call rum/request-render? What would that look like?

Does it make a difference if you know that the *app template will or will not execute within the 16ms frame limit?

lynaghk avatar Apr 09 '17 01:04 lynaghk

Batching state updates via requestAnimationFrame is usually a way to go. I believe most React wrappers does so.

So basically it's better to control how you update state and let the library to handle an update on its own.

roman01la avatar Apr 11 '17 08:04 roman01la