Does deep nesting flexbox layout cause performance issue?

前端 未结 2 1252
清歌不尽
清歌不尽 2021-02-12 20:17

I have been working on a ReactJS project where I create most of the components using flexbox layout. Since with react, we can have deeply nested components, so my layout is havi

相关标签:
2条回答
  • 2021-02-12 20:50

    Old flexbox (display: box) is 2.3x slower than new flexbox (display: flex). Regular block layout (non-float), will usually be as fast or faster than new flexbox since it’s always single-pass. But new flexbox should be faster than using tables or writing custom JS-base layout code. For more info Article1 Article2

    0 讨论(0)
  • 2021-02-12 21:06

    Have done a little test. Rendered 100 components, each with 10 nested layout. With and without flexbox. Here are the code snippets:

    Component/index.js

    @CSSModules(styles, { allowMultiple: true })
    export default class TheComponent extends Component {
      render() {
        const { deepNest, flex } = this.props
    
        return (
          <div>{ this.renderComp(deepNest, flex) }</div>
        )
      }
    
      renderComp(deepNest, flex) {
        const flexProperties = [
          { justifyContent: "center", alignItems: "center" },
          { justifyContent: "flex-start", alignItems: "flex-end" },
          { flexDirection: "row" }
        ]
    
        const content = [
          "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus interdum quis ligula vel elementum. Integer non rhoncus purus, eget dignissim ante.",
          "Lorem ipsum dolor sit amet, consectetur adipiscing elit.",
          "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus interdum quis ligula vel elementum. Integer non rhoncus purus, eget dignissim ante. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus interdum quis ligula vel elementum. Integer non rhoncus purus, eget dignissim ante."
        ]
    
        if (deepNest > 0 && flex) {
          return (
            <div styleName="containerFlex" style={flexProperties[deepNest % 3]}>
              <div styleName="contentFlex" style={flexProperties[deepNest % 3]}>
                { content[deepNest % 3] }
              </div>
              <div styleName="nestedFlex" style={flexProperties[deepNest % 3]}>
                { this.renderComp(deepNest - 1, flex) }
              </div>
            </div>
          )
        }
    
        if (deepNest > 0 && !flex) {
          return (
            <div styleName="container">
              <div styleName="content">
                Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus interdum quis ligula vel elementum. Integer non rhoncus purus, eget dignissim ante.
              </div>
              <div styleName="nested">
                { this.renderComp(deepNest - 1, flex) }
              </div>
            </div>
          )
        }
      }
    }
    

    WithFlex/index.js

    import TheComponent from "../Component"
    
    @CSSModules(styles, { allowMultiple: true })
    export default class WithFlex extends Component {
      constructor(props) {
        super(props)
    
        this.state = { render: false }
      }
    
      render() {
        const {render} = this.state
    
        // number of components to render
        const arr = _.range(100)
    
        return (
          <div>
            <div
            style={{ display: "block", padding: 30, lineHeight: "60px" }}
            onClick={() => this.setState({render: !render})}>
                Start Render
            </div>
    
            { render && arr.map((i) => <TheComponent key={i} deepNest={10} flex={true}/> ) }
          </div>
        )
      }
    }
    

    WithoutFlex/index.js

    import TheComponent from "../Component"
    
    @CSSModules(styles, { allowMultiple: true })
    export default class WithoutFlex extends Component {
      constructor(props) {
        super(props)
    
        this.state = { render: false }
      }
    
      render() {
        const {render} = this.state
    
        // number of components to renders
        const arr = _.range(100)
    
        return (
          <div>
            <div
            style={{ display: "block", padding: 30, lineHeight: "60px" }}
            onClick={() => this.setState({render: !render})}>
                Start Render
            </div>
    
            { render && arr.map((i) => <TheComponent key={i} deepNest={10} flex={false}/> ) }
          </div>
        )
      }
    }
    

    Results from Chrome dev-tool timeline.

    WithFlex

    WithoutFlex

    Summary

    The difference is not that much. Also in flexbox, I put random properties to choose from. So I think it's alright with the performance. Hope it will help other devs.

    0 讨论(0)
提交回复
热议问题