性能优化建议一:优化图片
系统内使用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:支持传入true和false
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)。
核心思路分两步:
- 图片设置一个默认图片,同时把真实图片地址存放到data-src属性上面;
- 监听页面滚动,图片滚动到可视区域后将data-src属性复制给src,加载真实图片;
性能优化建议八:优化代码风格
- 删除无用代码;
- 尽量去掉eslint-disabled字样;
- 解决eslint标红提示;
- 格式化代码。
性能优化建议九:创建私有仓库
构建私有仓库
性能优化建议十:使用公共变量
代码里一些变量使用时,先考虑下less、sass、utils、config等文件是否已经定义:
- 如果已经定义,请使用已定义变量;
- 如果未定义,需要定义为公共变量时请定义在相关公共文件内,如果不需要定义为公共变量时请定义在相关页面或功能内。
性能优化建议十一:组件化
编写组件(业务组件、公共组件)尽量使用组件化思想进行代码编写。
性能优化建议十二:其他React最佳实践
React 性能优化最佳实践(十九) - 掘金 (juejin.cn)
性能优化建议十三:Vue性能优化
揭秘 Vue.js 九个性能优化技巧 - 掘金 (juejin.cn)
性能优化建议十四:TS
根据需要,后期适当引入ts。