201903019 react基础之性能优化

博客介绍了生产环境和开发环境的相关优化内容。生产环境中,结尾为.min.js的文件适合使用,还可创建高效的Browserify和Webpack版本,用process.env判断环境。开发环境里,可避免协调、重写shouldComponentUpdate方法,还介绍了PureComponent的浅比较及针对其做的优化。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

生产环境

  • 单文件版本

    只有结尾是.min.js的文件才适合生产使用。

  • 创建更高效的Browserify生产版本

    npm install --save-dev bundle-collapser envify uglify-js uglifyify 
    # bundle-collapser 该插件用数字替代了长长的模块ID 
    # envify 该插件确保正确的编译环境
    # uglifyify 该插件移除了开发接口
    # uglify-js 整合以上所有
    
  • 创建更高效的Webpack生产版本

    使用process.env判断环境,包括一些压缩,删除注释,隐藏警告等功能。

    new webpack.DefinePlugin({
      'process.env': {
        NODE_ENV: JSON.stringify('production')
      }
    }),
    new webpack.optimize.UglifyJsPlugin()
    

开发环境

  • 避免协调

    当一个组件的props和state改变时,react会把新的数据和之前的数据做对比,不相等时再更新实际的dom。

  • shouldComponentUpdate

    但是我们也可以通过重写生命周期的shouldComponentUpdate方法来提升速度,因为这个方法是在重新渲染之前触发的。官网例子:

    class CounterButton extends React.Component {
      constructor(props) {
        super(props);
        this.state = {count: 1};
      }
    
      shouldComponentUpdate(nextProps, nextState) {
        if (this.props.color !== nextProps.color) {
          return true;
        }
        if (this.state.count !== nextState.count) {
          return true;
        }
        return false;
      }
    
      render() {
        return (
          <button
            color={this.props.color}
            onClick={() => this.setState(state => ({count: state.count + 1}))}>
            Count: {this.state.count}
          </button>
        );
      }
    }
    
  • PureComponent

    纯组件,是react提供的一个辅助对象,实现属性和值的一个‘浅比较’,可以减少不必要的render操作次数。

    • 如何浅比较 a和b是否相等

      • 都是基本类型 比较值,值相同:true;值不同:false
      • 都是引用类型,同一引用对象:true;不同引用对象:依次比较 长度 属性 属性值
      • 一个基本类型一个引用类型:false

      注意同一引用对象是个坑,数据前后发生了变化,但是因为是同一引用对象,所以导致没有更新。

    • 针对浅比较所做的优化

      • 易变数据不能使用一个引用
        class App extends PureComponent {
        state = {
          items: [1, 2, 3]
        }
        handleClick = () => {
          const { items } = this.state;
          items.pop();
          // 因为items使用的是同一个引用,所以如论怎么改变,都不会render
          this.setState({ items });
          // 优化方法:使用concat,每次改变都会产生一个新的数组
          this.setState({ items: [].concat(items) });
        }
        render() {
          return (<div>
            <ul>
              {this.state.items.map(i => <li key={i}>{i}</li>)}
            </ul>
            <button onClick={this.handleClick}>delete</button>
          </div>)
        }
        

      }

  • 不变数据使用一个引用

    < MyInput onChange={e => this.props.update(e.target.value)} />
    update(e) {
      this.props.update(e.target.value)
    }
    render() {
      return < MyInput onChange={this.update.bind(this)} />
    }
    // 上面的做法:每次render操作onChange都会返回一个新的函数,由于引用不一样,父组件的render也会导致子组件的render
    // 所以尽量避免这样的写法,最后按下面的做法:
    update = (e) => {
      this.props.update(e.target.value)
    }
    render() {
      return < MyInput onChange={this.update)} />
    }
    
  • 不突变原始对象的方法的整理

    this.setState(prevState => ({
      words: prevState.words.concat(['marklar'])
    }));
    this.setState(prevState => ({
      words: [...prevState.words, 'marklar'],
    }));
    
    colormap.right = 'blue';
    Object.assign({}, colormap, {right: 'blue'});
    {...colormap, right: 'blue'}
    
    // 不可突变的数据结构: Immutable
    const SomeRecord = Immutable.Record({ foo: null });
    const x = new SomeRecord({ foo: 'bar' });
    const y = x.set('foo', 'baz');
    x === y; // false
    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值