React性能提升小建议

139 阅读2分钟

以下内容有什么不对的地方请各位多多指教。鞠躬!

1. 使用useMemo和PureComponent组件

减少组件不必要的渲染

 <!--如果propsA属性有变化 componentB组件也会重新渲染-->
    const app = props => {
        return (
            <div>
                <ComponentA propsA={props.A} />
                <ComponentB propsB={props.B} />
            </div>
        )
    }
    
    const ComponentA = props => <div>this is {props.propsA}!</div>
    const ComponentB = props => <div>this is {props.propsB}!</div>

2. 避免匿名函数

<!--匿名函数不会留存在内存空间-->
    const app = () => (
        <div onClick={() => console.log('click')}>click</div>
    )

这样写主要导致的问题就是react的重复渲染(针对无状态组件),处理方法如下

    // 1. 有名函数 且 写在组件外面
    const click = () => console.log('happen')
    const comA = () => (
        <div onClick={click}>this is comA</div>
    )
    
    // 2. useCallback
    import React, { useCallback } from 'react'
    const comB = () => {
        const click = useCallback(()=> console.log('click'), [])
        return <div onClick={click}>this is comB</div>
    }

3. 避免在组件内直接使用对象

原理跟匿名函数的问题一样,对象不会留存在内存空间。即使使用pureComponent或者useMemo,react的组件依然会重新渲染

    // 错误事例
    function ComponentA() {
      return (
        <div>
          HELLO WORLD
          <ComponentB style={{  {/* 避免这种情况️ */}
            color: 'blue',     
            background: 'gold'
          }}/>
        </div>
      );
    }
        
    function ComponentB(props) {
      return (
        <div style={this.props.style}>
          TOP OF THE MORNING TO YA
        </div>
      )
    }
    // 解决方案
    const styles = {
        color: 'blue',     
        background: 'gold'
    }
    
    function ComponentA() {
      return (
        <div>
          HELLO WORLD
          <ComponentB style={styles}/>
        </div>
      );
    }
    
    function ComponentB(props) {
      return (
        <div style={this.props.style}>
          TOP OF THE MORNING TO YA
        </div>
      )
    }

4. 使用react.lazy和react.suspense(react 16.0 +)

使用代码分割,使打包文件体积变小,在懒加载时再加载文件,使页面加载更迅速。

import React, { lazy, Suspense } from 'react';
import Header from './Header';
import Footer from './Footer';
const BlogPosts = React.lazy(() => import('./BlogPosts'));

function MyBlog() {
  return (
    <div>
      <Header>
      <Suspense fallback={<div>Loading...</div>}> //未加载组价时
        <BlogPosts />
      </Suspense>
      <Footer>
    </div>
  );
}

5. 减少频繁的挂载/卸载

频繁的挂载/卸载组件, 在组件被移除时,页面就会发生重排/重绘。

<!--错误示范-->
import React, { Component } from 'react';
import DropdownItems from './DropdownItems';

class Dropdown extends Component {
  state = {
    isOpen: false
  }
  render() {
    <a onClick={this.toggleDropdown}>
      Our Products
      {
        this.state.isOpen
          ? <DropdownItems>
          : null
      }
    </a>
  }
  toggleDropdown = () => {
    this.setState({isOpen: !this.state.isOpen})
  }
}
解决方案:
通过设置css opacity: 0 或者 visiable: 'none'.
这样做会使组件留在DOM中,同时也使组件有效的消失且不增加任何的性能消耗。

6. 使用shouldComponentUpdate

react组件默认shouldComponentUpdate为true, 使用该方法可以有效地避免react组件重复渲染问题。