[英]Avoid re-rendering on scroll and increase performance in a React web application
我有React的性能問題,基本上我有2個緊湊的菜單,當頁面滾動到距離頂部x距離時。 正如我所看到的,當我滾動時,Web應用程序的另一個組件正在做很少的動作,原因是它們正在重新渲染。
要知道當用戶進行滾動時到頂部的距離我在componentDidMount()上有一個eventlistener,我認為這導致了問題,但我不確定,因為你知道反應穩定的版本是相當新的,我'這也是這項技術的新成員:
下面是一些代碼,正好是嵌套組件的頂部欄,當用戶從頂部滾動超過100px時觸發緊湊菜單欄:
export default class AppTopBar extends Component {
constructor (props){
super(props);
this._bind("_handleOnScrollDocument");
this.state = {
StatusBar: false
}
}
componentDidMount() {
if (process.env.BROWSER) {
document.addEventListener("scroll", (e) => this._handleOnScrollDocument(e), true);
}
}
_handleOnScrollDocument(e) {
if (e.target.body.scrollTop > 100) {
this.setState({ StatusBar: true });
} else {
this.setState({ StatusBar: false });
}
}
render() {
return (
<div className="aui-core-apptopbar">
<StatusBar companies={this.props.companies} compactMenuItems={this.props.compactMenuItems} StatusBar={this.state.showCompactStatusBar}/>
<StatusBar companies={this.props.companies} userOptions={this.props.userOptions} compactMenuItems={this.props.compactMenuItems}/>
<MainNavBarView menuItems={this.props.menuItems}/>
</div>
);
}
}
我一直在研究和閱讀有關組件生命周期和其他性能的信息: PURERENDERMIXIN
您是否知道更好的方法來獲取輕量級Web應用程序並避免重新呈現滾動?
假設您為類創建了一個局部變量flag
。 接着:
_handleOnScrollDocument(e) {
let newFlag = (e.target.body.scrollTop > 100);
if (flag !== newFlag) {
this.setState({showCompactStatusBar: newFlag});
flag = newFlag;
}
};
僅當您從一個方向或其他方向傳遞scrollTop閾值(100)時,這將導致狀態更改(和重新呈現)。 否則我們根本不需要設置狀態,從而避免調用render
。
“內置”解決方案是使用shouldComponentUpdate
方法,該方法允許您將組件的當前props
和state
與傳入的 props
和state
,然后在選擇時將render
方法短路:
_handleOnScrollDocument(e) {
// set the state no matter what
this.setState({
showCompactStatusBar: e.target.body.scrollTop > 100
});
},
shouldComponentUpdate(newProps, newState) {
// only render if the state has changed
return this.state.showCompactStatusBar !== newState.showCompactStatusBar;
}
我在頁面內的組件上有一個滾動事件,它有overflow: auto
CSS規則。 我將滾動事件監聽器附加到該組件,因為它在此博客文章中被引導。 但是,將最后一個滾動位置設置為狀態會嚴重破壞性能。
因此,我在類構造函數中定義了最后一個位置並在那里更改了它,並避免了在每個滾動上重新渲染。
constructor(props){
super(props)
this.state = { scrollDirection: 'up' }
this.lastY = 0
}
如果方向改變,我只會改變狀態。
handleListScroll(event){
const Y = event.currentTarget.scrollTop
const lastY = this.lastY
if (Y > lastY) {
scrollDirection = 'down'
if (this.state.scrollDirection === 'up') {
this.setState({
scrollDirection,
})
}
}
if (Y < lastY) {
scrollDirection = 'up'
if (this.state.scrollDirection === 'down') {
this.setState({
scrollDirection
})
}
}
this.lastY = Y
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.