簡體   English   中英

避免重新渲染滾動並提高React Web應用程序的性能

[英]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方法,該方法允許您將組件的當前propsstate傳入的 propsstate ,然后在選擇時將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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM