Skip to content

Instantly share code, notes, and snippets.

@evanrs
Last active December 10, 2021 22:08
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save evanrs/7df442d411c5eb0baacdec3f4bab6879 to your computer and use it in GitHub Desktop.
Save evanrs/7df442d411c5eb0baacdec3f4bab6879 to your computer and use it in GitHub Desktop.

When it comes to memo'ization any option will be valid if it meets the following three criteria.

1. Will this work be closer to the root, or the leaf?

As we approach the leaves of the component tree the impact of memo'ization will be diminished as the number of impacted children decreases.

As the number of potential children increases we offer a corresponding level of care in making sure our values only update when there's a pertinent change to that value.

2. Where will my work be used?

We should be confident about where our work will be used — if we're not sure then we need to answer this question first.

If our work will be used broadly, then there is almost no cost to memoization versus the cost of re-renders as the component tree scales.

If our work is not used broadly, but instead has n number of instances as we map over a large set of data — then again, the cost of memoization decreases as the cardinality of use increases.

But, if our work doesn't create a map of instances, and it's used one or twice, close to the leaf. This is where we can choose not to memoize — memoizing at the edge will have the greatest negative impact to performance.

3. Does my work involve a user interaction?

With this one exception — the whole purpose of an application is interactivity. Inputs, buttons, bottom sheets, swipe gestures — they're all at the leaf.

Anything that could introduce delay to a user interaction — the ability for the app to respond instantaneously — must be dealt with.

The way we avoid stalling the app — where's its most critical — is through tight control of value change. We must know that the inputs to our component and our hooks are immutable. That the value of the reference we take are immutable. For highly crafted experiences we'll even introduce a stage and commit phase too. That's where we intentionally delay propagating a change that is not yet essential to a user's feeling of speed.

The most common use case is to debounce an input. For example, querying over the network to provide search results. Querying per key will slow it down, but re-rendering because we have updated the results will slow it down even more.

So, we debounce the input, perform the minimal number of requests, discard the intermediate responses, and stage our updates with respect to user activity. Heck, we may even stage our update over multiple renders if it were deterimental to do it all at once.

So, when do we memoize?

  • when we're close to the root
  • when we have many dependents
  • when we expect a large number of instances
  • when we are involved with user interactivity
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment