Performance in React
Performance Issue in React Detected With Why Did You Render
HTML
<script src="https://www.npmjs.com/package/@welldone-software/why-did-you-render"></script>
<div id="app"></div>
CSS
body {
padding: 0;
margin: 0;
}
.App {
font-family: sans-serif;
text-align: center;
display: flex;
flex-direction: column;
}
.Header {
position: fixed;
left: 10px;
top: 0;
right: 10px;
display: flex;
flex-direction: column;
background-color: pink;
overflow: hidden;
}
.Header .Heading {
padding: 10px 30px;
display: flex;
flex-direction: row;
}
.Header .PureInput {
padding: 10px 30px;
}
.Header .ScrollIndication {
display: flex;
flex-direction: column;
}
.Header .ScrollIndication > span {
padding: 5px;
}
.Main {
display: flex;
flex-direction: column;
background-color: aquamarine;
}
.Row {
margin: 5px;
padding: 10px;
border: #666 solid 1px;
display: flex;
flex-direction: row;
justify-content: space-between;
}
React
const { useState, useEffect } = React;
const App=()=> {
useHeaderScroll({
min: 50,
max: 350,
maxOffset: 3000
});
return (
<div className="App">
<Header style={{ height: "80px" }} />
<Main style={{ paddingTop: "200px" }}/>
</div>
);
}
const Header = ({ style }) => (
<header className="Header" style={style}>
<div className="ScrollIndication">
<span>SCROLL</span>
<span role="img" aria-label="scroll down!">
👇
</span>
</div>
</header>
);
let numberOfRenders = 0;
const Main =({style}) => {
console.log(`Rendering Main for the ${++numberOfRenders} time`);
return (
<div className="Main" style={style}>
{Array.from(Array(3000), (item, rowNumber) => (
<div className="Row" key={rowNumber}>
<div>Row Icon</div>
<div>Some Text - Row {rowNumber}</div>
<button>Button that does something</button>
</div>
))}
</div>
);
};
// based on "use-header-scroll" from https://github.com/nir905/use-header-scroll#readme
const useHeaderScroll = ({ min, max, target = window, maxOffset }) => {
const [height, setHeight] = useState(max);
useEffect(() => {
const onScroll = () => {
const percent = 1 - Math.min(1, target.scrollY / maxOffset);
setHeight(percent * (max - min) + min);
};
// { passive: true } would be a good idea,
// if I wouldn't want to intentially make scrolling a little slower then usual
target.addEventListener("scroll", onScroll);
return () => target.removeEventListener("scroll", onScroll);
}, [min, max, target, maxOffset]);
return height;
};
ReactDOM.render(<App />, document.getElementById("app"))