Search code examples
reactjsclojurescriptreagent

How to cache or prevent re-render of large reagent component


I have a reagent single page application. At the root component, I have a route dispatcher that renders component according to route. Something like:

(defn page []
  [(get component-lookup @current-page-name)])

I have a list page and a detail page, where user frequently switches back and forth.

Problem is, switching between these two pages destroys and re-create an entire page worth of components. This slows down page transition noticeably, especially in mobile devices. In contrast, switching from one detail page to another is very fast, as react figured only a few components need to be re-rendered.

My first attempt at optimization is to have both pages rendered all the time, but add display:none whenever they are not visible. This speeds up page transition, but changes the meaning of lifecycle methods. For example, component-did-mount would execute, but the component is not visible and I cannot update its scroll position.

Would there be a better way to do this? Maybe it is possible to unmount a component tree, save it along with its subcomponents and states/virtual dom, to be remounted later with new props?


Solution

  • I don't think you're going to be able to do this without forking react. The lifecycles are inherently tied to modifications to the virtual dom--that's their whole point of existence.

    It's a little surprising that the mere rendering of the DOM elements are too slow, unless your page has thousands of dom elements or lots of media. What are you doing during mount? If it is compute intensive, I'd look there to see if you can separate out that logic and cache it so that it is a lightweight process to switch components.