React Render Performance
Tyler Graf
Web Dev
Tree Team


React Render Lifecycle

2. Commit
Make diff changes appear in the DOM
1. Render
Run a diff for all components.
Phases
Virtual DOM Diffing



import React, { Component } from "react";
export default class Counter extends Component {
constructor(props) {
super(props);
}
shouldComponentUpdate(oldProps, newProps) {}
render({ currentCount, handleAdd, handleSubtract }) {
return (
<div>
<HeaderBlock size="lg" heading="Counter Example" />
<p>Count: {currentCount}</p>
<IconButton onClick={handleAdd} Icon={ContentAdd} />
<IconButton onClick={handleSubtract} Icon={ContentRemove} />
</div>
);
}
componentWillUnmount() {}
componentDidUpdate() {}
componentDidMount() {}
}
Class Component
import React, { Component } from "react";
export default class Counter extends Component {
constructor(props) {
super(props);
}
shouldComponentUpdate(oldProps, newProps) {}
render({ currentCount, handleAdd, handleSubtract }) {
return (
<div>
<HeaderBlock size="lg" heading="Counter Example" />
<p>Count: {currentCount}</p>
<IconButton onClick={handleAdd} Icon={ContentAdd} />
<IconButton onClick={handleSubtract} Icon={ContentRemove} />
</div>
);
}
componentWillUnmount() {}
componentDidUpdate() {}
componentDidMount() {}
}
Functional Component
import React, { Component } from "react";
export default function Counter({ currentCount, handleAdd, handleSubtract }) {
const coolCss = css`
display: flex;
`
return (
<div css={coolCss}>
<HeaderBlock size="lg" heading="Counter Example" />
<p>Count: {currentCount}</p>
<IconButton onClick={handleAdd} Icon={ContentAdd} />
<IconButton onClick={handleSubtract} Icon={ContentRemove} />
</div>
);
}
import React, { Component } from "react";
const coolCss = css`
display: flex;
`
export default function Counter({ currentCount, handleAdd, handleSubtract }) {
return (
<div css={coolCss}>
<HeaderBlock size="lg" heading="Counter Example" />
<p>Count: {currentCount}</p>
<IconButton onClick={handleAdd} Icon={ContentAdd} />
<IconButton onClick={handleSubtract} Icon={ContentRemove} />
</div>
);
}
import React, { Component } from "react";
export default class Counter extends Component {
constructor(props) {
super(props);
}
shouldComponentUpdate(oldProps, newProps) {
return oldProps.currentCount === newProps.currentCount
}
render({ currentCount, handleAdd, handleSubtract }) {
return (
<div>
<HeaderBlock size="lg" heading="Counter Example" />
<p>Count: {currentCount}</p>
<IconButton onClick={handleAdd} Icon={ContentAdd} />
<IconButton onClick={handleSubtract} Icon={ContentRemove} />
</div>
);
}
componentWillUnmount() {}
componentDidUpdate() {}
componentDidMount() {}
}
Conditional Re-rendering
Conclusion:
Move to Class Components

React perf functions
React.memo
React.useCallback
React.useMemo
React.memo
import React from 'react'
import { IconButton, HeaderBlock } from '@fs/zion-ui'
import { ContentAdd, ContentRemove } from '@fs/zion-icon'
export default function Counter({ currentCount, handleAdd, handleSubtract }) {
return (
<div>
<HeaderBlock size="lg" heading="Counter Example" />
<p>Count: {currentCount}</p>
<IconButton onClick={handleAdd} Icon={ContentAdd} />
<IconButton onClick={handleSubtract} Icon={ContentRemove} />
</div>
)
}
import React, { memo } from 'react'
import { IconButton, HeaderBlock } from '@fs/zion-ui'
import { ContentAdd, ContentRemove } from '@fs/zion-icon'
function Counter({ currentCount, handleAdd, handleSubtract }) {
return (
<div>
<HeaderBlock size="lg" heading="Counter Example" />
<p>Count: {currentCount}</p>
<IconButton onClick={handleAdd} Icon={ContentAdd} />
<IconButton onClick={handleSubtract} Icon={ContentRemove} />
</div>
)
}
export default memo(Counter)
import React, { memo } from 'react'
import { IconButton, HeaderBlock } from '@fs/zion-ui'
import { ContentAdd, ContentRemove } from '@fs/zion-icon'
function Counter({ currentCount, handleAdd, handleSubtract }) {
return (
<div>
<HeaderBlock size="lg" heading="Counter Example" />
<p>Count: {currentCount}</p>
<IconButton onClick={handleAdd} Icon={ContentAdd} />
<IconButton onClick={handleSubtract} Icon={ContentRemove} />
</div>
)
}
export default memo(Counter, (oldProps, newProps)=>{
return oldProps.currentCount === newProps.currentCount
})
Used for memoizing components
React.useCallback
import React, { memo, useState } from 'react'
import { IconButton, HeaderBlock } from '@fs/zion-ui'
import { ContentAdd, ContentRemove } from '@fs/zion-icon'
function Counter({ handleSubtract }) {
const [currentCount, setCurrentCount] = useState(0)
const handleAdd = ()=>{
setCurrentCount(oldCount=>oldCount + 1)
}
return (
<div>
<HeaderBlock size="lg" heading="Counter Example" />
<p>Count: {currentCount}</p>
<IconButton onClick={handleAdd} Icon={ContentAdd} />
<IconButton onClick={handleSubtract} Icon={ContentRemove} />
</div>
)
}
export default memo(Counter)
import React, { memo, useState, useCallback } from 'react'
import { IconButton, HeaderBlock } from '@fs/zion-ui'
import { ContentAdd, ContentRemove } from '@fs/zion-icon'
function Counter({ handleSubtract }) {
const [currentCount, setCurrentCount] = useState(0)
const handleAdd = useCallback(()=>{
setCurrentCount(oldCount=>oldCount + 1)
}, [ setCurrentCount ])
return (
<div>
<HeaderBlock size="lg" heading="Counter Example" />
<p>Count: {currentCount}</p>
<IconButton onClick={handleAdd} Icon={ContentAdd} />
<IconButton onClick={handleSubtract} Icon={ContentRemove} />
</div>
)
}
export default memo(Counter)
Used for memoizing functions
React.useMemo
import React, { memo, useCallback, useMemo } from 'react'
import { IconButton, HeaderBlock } from '@fs/zion-ui'
import { ContentAdd, ContentRemove } from '@fs/zion-icon'
function Counter({ currentCount, handleSubtract }) {
const handleAdd = useCallback(()=>{
console.log('add')
},[])
const sinValue = useMemo(() => Math.sin(currentCount),[currentCount])
return (
<div>
<HeaderBlock size="lg" heading="Counter Example" />
<p>Count: {currentCount}</p>
<p>Sin Value: {sinValue}</p>
<IconButton onClick={handleAdd} Icon={ContentAdd} />
<IconButton onClick={handleSubtract} Icon={ContentRemove} />
</div>
)
}
export default memo(Counter)
import React, { memo, useCallback } from 'react'
import { IconButton, HeaderBlock } from '@fs/zion-ui'
import { ContentAdd, ContentRemove } from '@fs/zion-icon'
function Counter({ currentCount, handleSubtract }) {
const handleAdd = useCallback(()=>{
console.log('add')
},[])
const sinValue = Math.sin(currentCount)
return (
<div>
<HeaderBlock size="lg" heading="Counter Example" />
<p>Count: {currentCount}</p>
<p>Sin Value: {sinValue}</p>
<IconButton onClick={handleAdd} Icon={ContentAdd} />
<IconButton onClick={handleSubtract} Icon={ContentRemove} />
</div>
)
}
export default memo(Counter)
Used for memoizing values
React dev tools extension
Demo
React Render Performance
By Tyler Graf
React Render Performance
- 679