Meiosis Wiki

Table of Contents

Preventing Re-renders

IMPORTANT NOTE: before preventing re-renders, please first make sure that re-rendering a part of your application is indeed causing a performance problem that impacts the user experience. Producing a virtual DOM node and re-rendering by the engine is generally fast, especially relative to everything else that is going on in a web application: database access, network requests, and so on. Avoid premature optimization!

Also consider the UI: if a table with thousands of rows of data is responsible for slowing down your application, ask yourself whether users want to look at all that data at once on the page. Perhaps pagination would be more appropriate? Or, think about whether adding some filters will help users narrow down what they are looking for.

If you still need to prevent re-rendering, read on for the React version, or scroll down to the Mithril version.

React version

We can use React's PureComponent to prevent a component from re-rendering when the model has not changed. For this to work, we need to make sure to produce new object instances from update() instead of mutating the existing object.

For example, instead of issuing an update like so:

update(model => Object.assign(model, { value: evt.target.value }))

We switch to:

update(model => Object.assign({}, model, { value: evt.target.value }))

This creates a new object instance instead of mutating the model.

Next, instead of extending React.Component:

return class extends React.Component {
  //...
}

We now extend React.PureComponent:

return class extends React.PureComponent {
  //...
}

This will prevent the component's render() method from being called when the model has not changed. We can prove this to ourselves by adding console.log statements in the render() methods of the components, and check the console output to confirm that components are only re-rendered when their model has changed.

Verify this in the example below. Notice that render Entry, render Date, render Temperature Air, and render Temperature Water appear in the console output only when you interact with that component in the user interface. Other components do not get re-rendered.

Mithril version

We can use Mithril's onbeforeupdate lifecycle method to prevent a component from re-rendering when the model has not changed. For this to work, we need to make sure to produce new object instances from update() instead of mutating the existing object.

Because we are using Patchinko to issue and handle model updates, this is simply a matter of switching from overloaded to immutable. This creates a new object instance instead of mutating the model.

Next, we can write a simple helper function that checks whether the component's model has changed:

const checkIfModelChanged = (next, prev) =>
  next.attrs.model !== prev.attrs.model;

Finally, we add the onbeforeupdate lifecycle method to the component:

onbeforeupdate: checkIfModelChanged

This will prevent the component's view() method from being called when the model has not changed. We can prove this to ourselves by adding console.log statements in the view() methods of the components, and check the console output to confirm that components are only re-rendered when their model has changed.

Verify this in the example below. Notice that render Entry, render Date, render Temperature Air, and render Temperature Water appear in the console output only when you interact with that component in the user interface. Other components do not get re-rendered.

Table of Contents


Meiosis is developed by @foxdonut00 / foxdonut and is released under the MIT license.