<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.13.1/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.13.1/umd/react-dom.production.min.js"></script>
<div id="root"></div>
function ComponentWithInlineFunction() {
const clickMe = () => {
}
return React.createElement('button', {
onClick: clickMe
}, 'Click me!')
}
function ComponentWithUseCallback() {
const clickMe = React.useCallback(() => {
}, [])
return React.createElement('button', {
onClick: clickMe
}, 'Click me!')
}
function ComponentWithoutUseMemo() {
const obj = {
x: 1,
y: 1
}
return React.createElement('h1', {
data: obj
}, 'ComponentWithoutUseMemo')
}
function ComponentWithUseMemo() {
const obj = React.useMemo(() => ({
x: 1,
y: 1
}), [])
return React.createElement('h1', {
data: obj
}, 'ComponentWithUseMemo')
}
const ChildWithoutMemo = () => {
return React.createElement('div', null, null)
}
const ChildWithMemo = React.memo(ChildWithoutMemo)
function ComponentWithoutMemorizedChild() {
const [count, setCount] = React.useState(0)
React.useEffect(() => {
if (count < 10000) {
setCount(c => c + 1)
}
})
return React.createElement(ChildWithoutMemo, null, null)
}
function ComponentWithMemorizedChild() {
const [count, setCount] = React.useState(0)
React.useEffect(() => {
if (count < 10000) {
setCount(c => c + 1)
}
})
return React.createElement(ChildWithMemo, null, null)
}
ReactDOM.render(React.createElement(ComponentWithInlineFunction), document.getElementById('root'))
ReactDOM.render(React.createElement(ComponentWithUseCallback), document.getElementById('root'))
ReactDOM.render(React.createElement(ComponentWithoutUseMemo), document.getElementById('root'))
ReactDOM.render(React.createElement(ComponentWithUseMemo), document.getElementById('root'))
ReactDOM.render(React.createElement(ComponentWithoutMemorizedChild), document.getElementById('root'))
ReactDOM.render(React.createElement(ComponentWithMemorizedChild), document.getElementById('root'))
--enable-precise-memory-info
flag.
Test case name | Result |
---|---|
Inline Function | |
Hooks | |
Without useMemo | |
With useMemo | |
Child without memo | |
Child with memo |
Test name | Executions per second |
---|---|
Inline Function | 415913.5 Ops/sec |
Hooks | 514671.5 Ops/sec |
Without useMemo | 264508.4 Ops/sec |
With useMemo | 512767.3 Ops/sec |
Child without memo | 290595.8 Ops/sec |
Child with memo | 314925.8 Ops/sec |
I'll break down the benchmark and explain what's being tested.
Benchmark Overview
The benchmark compares four approaches to optimize React components:
const clickMe = () => { ... }
)React.useCallback
)useMemo
(using a simple object as state)useMemo
(using the useMemo
hook to memoize a complex object)Options Compared
The benchmark tests the performance of each approach under different conditions:
useMemo
vs. With useMemo
Pros and Cons
Here's a brief summary of the pros and cons of each approach:
useMemo
: Pros - no additional dependency array required; Cons - can lead to unnecessary re-renders, slower performance.useMemo
: Pros - optimizes computationally expensive operations; Cons - requires manual management of dependencies.Library and Purpose
The benchmark uses React, a popular JavaScript library for building user interfaces. The useCallback
, useMemo
, and React.memo
hooks are used to implement the different optimization approaches.
useCallback
: A hook that memoizes a function, so it's only recreated when its dependencies change.useMemo
: A hook that memoizes a value, so it's only recalculated when its dependencies change.React.memo
: A higher-order component that memoizes a component, so it's only re-rendered when its props change.Special JS Feature or Syntax
The benchmark uses React-specific features and syntax, such as:
useCallback
useMemo
React.memo
No other special JavaScript features or syntax are used in this benchmark.
I hope this explanation helps you understand the benchmark!