React Bailout Perf Test
by wuct
HTML
<script src="https://unpkg.com/eventemitter2/lib/eventemitter2.js"></script>
<script src="https://unpkg.com/[email protected]/dist/react-with-addons.min.js"></script>
<script src="https://unpkg.com/[email protected]/dist/react-dom.min.js"></script>
<div id="root"></div>
Babel + JSX
const Dot = ({ cx, cy, r }) => {
return (
<circle
fill="#013f8e"
cx={cx}
cy={cy}
r={r}
/>
)
}
let ID = 0
const dots = []
for (let i = 0; i < 200; i++) {
dots.push(React.createElement(Dot, {
key: ID++,
cx: Math.ceil(Math.random() * 200),
cy: Math.ceil(Math.random() * 200),
r: Math.ceil(Math.random() * 4)
}))
}
const Dots = () => {
return (
<svg viewBox="0 0 200 200">
{dots}
</svg>
)
}
class Parent extends React.Component {
render() {
return this.props.children
}
}
const staticObject = {}
class ParentWithContext extends React.Component {
static childContextTypes = {}
getChildContext() {
return staticObject
}
render() {
return this.props.children
}
}
const rootEle = document.getElementById('root')
// Start perf test
console.log('Start testing...')
const parent = ReactDOM.render(
<Parent><Dots /></Parent>, rootEle
)
const NUM_OF_UPDATES = 100
updateInstanceByTimes(parent, NUM_OF_UPDATES)
.then((results) => {
console.log('With Bailout: ')
renderResults(results)
ReactDOM.unmountComponentAtNode(rootEle)
// Start perf test without bailout
const parentWithContext= ReactDOM.render(
<ParentWithContext><Dots /></ParentWithContext>, rootEle
)
return updateInstanceByTimes(parentWithContext, NUM_OF_UPDATES)
})
.then((results) => {
console.log('\n\n')
console.log('Without Bailout: ')
renderResults(results)
})
// Test Utils
function updateInstanceByTimes(instance, numOfTimes) {
return new Promise((resolve) => {
const results = []
const updateInstance = () => instance.setState({})
for (let i = 0; i < numOfTimes; i ++) {
setTimeout(() => {
performTask(
updateInstance,
result => results.push(result)
)
}, i * 50) // update interval
}
setTimeout(() => {
const computed =
results.reduce((acc, { syncTime, asyncTime, total }) => ({
syncTime: acc.syncTime +...