REACT项目性能优化建议

164 阅读4分钟

性能优化建议一:优化图片

系统内使用png,jpe?g等图片,可以先在该网站tinypng.com/进行压缩后在,或跟美工沟通由美工出图后先压缩再给各位。

性能优化建议二:tree-shaking

在webpack项目打包的工程里,建议外部库使用ESM方式引入并且按需所需功能,会自动tree shaking,减少不必要代码的打包。

项目中用到的已测试过的库包括:crypto-js、echarts-for-react、loash

性能优化建议三:上传下载组件

上传下载组件已开启图片默认压缩且支持传入comporess={...opts}自定义压缩配置,也可通过compress=false关闭压缩。

compress支持传参类型:boolean|object

boolean:支持传入truefalse
    false:关闭自动压缩功能;
    true:开启自动压缩功能,且按照以下原则进行压缩:
        1. 默认压缩质量1,宽度2560
        2. 如果大小超过2M,压缩质量变为0.9

object:支持传入压缩配置,完整参数如下
    const comporess = {
      width: 2560, // 压缩后的图片宽度
      height: 1440, // 压缩后的图片高度
      quality: 1, // 压缩后的图片质量
      ingnoreOrientation: UA.iOS ? UA.newIOS : true, // 是否旋转图片
      MAX: 2, // 如果大小超过MAX,压缩质量变为SECOND_QUALITY
      SECOND_QUALITY: 0.95,
    };

性能优化建议四:InnerCustomBoundary

容易出错的功能块,请使用src/components/InnerCustomBoundary组件进行包裹。例如:

性能优化建议五:善用throttle(节流) & debounce(防抖)

  • 节流

节流的意思是,规定时间内,只触发一次。 比如我们设定500ms,在这个时间内,无论点击按钮多少次,它都只会触发一次。具体场景可以是抢购时候,由于有无数人 快速点击按钮,如果每次点击都发送请求,就会给服务器造成巨大的压力,但是我们进行节流后,就会大大减少请求的次数。例如:防止表单提交按钮被多次触发,我们应该选择使用节流。

import React from 'react';
import throttle from 'lodash/throttle';

class LoadMoreButton extends React.Component {
  constructor(props) {
    super(props);
    this.handleClick = this.handleClick.bind(this);
    this.handleClickThrottled = throttle(this.handleClick, 1000);
  }

  componentWillUnmount() {
    this.handleClickThrottled.cancel();
  }

  handleClick() {
    // eslint-disable-next-line no-console
    console.log('handleClick', this.state);
  }

  render() {
    return (
      <button type="submit" onClick={this.handleClickThrottled}>
        Load More
      </button>
    );
  }
}

export default LoadMoreButton;
  • 防抖

防抖的意思是,在连续的操作中,无论进行了多长时间,只有某一次的操作后在指定的时间内没有再操作,这一次才被判定有效。 具体场景可以搜索框输入关键字过程中实时 请求服务器匹配搜索结果,如果不进行处理,那么就是输入框内容一直变化,导致一直发送请求。如果进行防抖处理,结果就是当我们输入内容完成后,一定时间(比如500ms)没有再 输入内容,这时再触发请求。例如:页面滚动、搜索框输入关键字查询应该选择使用防抖。

import React from 'react';
import debounce from 'lodash/debounce';

class Searchbox extends React.Component {
  constructor(props) {
    super(props);
    this.handleChange = this.handleChange.bind(this);
    this.emitChangeDebounced = debounce(this.emitChange, 250);
  }

  componentWillUnmount() {
    this.emitChangeDebounced.cancel();
  }

  handleChange(e) {
    this.emitChangeDebounced(e.target.value);
  }

  emitChange(value) {
    // eslint-disable-next-line no-console
    console.log('handleClick', value, this.state);
  }

  render() {
    return (
      <input
        type="text"
        onChange={this.handleChange}
        placeholder="Search..."
        defaultValue="关键字"
      />
    );
  }
}

export default Searchbox;

性能优化建议六:善用动态组件

1.封装为动态组件(可参考src\pages\Index\components\MapCard\index.jsx)

import { dynamic } from 'umi';

export default dynamic({
  loader: async function genMapCard() {
    // 这里的注释 webpackChunkName 可以指导 webpack 将该组件 HugeA 以这个名字单独拆出去
    const { default: MapCard } = await import(/* webpackChunkName: "Index__MapCard" */ './MapCard');
    return MapCard;
  },
});

2.使用动态组件(和普通组件使用方式一样)

class Comp extends React.Component {
    // ...
   render() {
        return (
              <InnerCustomBoundary>
                <MapCard
                  className={styles.map}
                  center={mapCenter}
                  placeInfo={placeInfo}
                  onRef={this.MapCardRef}
                />
              </InnerCustomBoundary>
        )
    }
}

性能优化建议七:图片懒加载

有大量图片需要展示的地方请使用图片懒加载。具体可参考建筑信息模块(http://localhost:8000/ifss-operation-front/buildingManagement)。

核心思路分两步:

  1. 图片设置一个默认图片,同时把真实图片地址存放到data-src属性上面;
  2. 监听页面滚动,图片滚动到可视区域后将data-src属性复制给src,加载真实图片;

性能优化建议八:优化代码风格

  1. 删除无用代码;
  2. 尽量去掉eslint-disabled字样;
  3. 解决eslint标红提示;
  4. 格式化代码。

性能优化建议九:创建私有仓库

构建私有仓库

性能优化建议十:使用公共变量

代码里一些变量使用时,先考虑下less、sass、utils、config等文件是否已经定义:

  1. 如果已经定义,请使用已定义变量;
  2. 如果未定义,需要定义为公共变量时请定义在相关公共文件内,如果不需要定义为公共变量时请定义在相关页面或功能内。

性能优化建议十一:组件化

编写组件(业务组件、公共组件)尽量使用组件化思想进行代码编写。

性能优化建议十二:其他React最佳实践

React 性能优化最佳实践(十九) - 掘金 (juejin.cn)

性能优化建议十三:Vue性能优化

揭秘 Vue.js 九个性能优化技巧 - 掘金 (juejin.cn)

性能优化建议十四:TS

根据需要,后期适当引入ts。