问题场景:
公司管理层报表太多有上百张,加载缓慢,需要近50s才能加载出前面的页面,并且图表加载顺序都是随机的,前面的图表可能会在最后才渲染出来,给人极慢的体验。
问题解决:
在上面👆的目录中对Dashboard组件进行源码分析,并改造
代码参考👇 主要是对请求顺序和渲染顺序进行队列排序,由广度改为深度。
import React from 'react';
import PropTypes from 'prop-types';
import { bindActionCreators } from 'redux';
import { connect } from 'react-redux';
import { logEvent } from 'src/logger/actions';
import { addDangerToast } from 'src/messageToasts/actions';
import { componentLookup } from '../components/gridComponents';
import getDetailedComponentWidth from '../util/getDetailedComponentWidth';
import { getActiveFilters } from '../util/activeDashboardFilters';
import { componentShape } from '../util/propShapes';
import { COLUMN_TYPE, ROW_TYPE } from '../util/componentTypes';
import Loading from 'src/components/Loading';
import {
createComponent,
deleteComponent,
updateComponents,
handleComponentDrop,
} from '../actions/dashboardLayout';
import {
setDirectPathToChild,
setActiveTabs,
setFullSizeChartId,
} from '../actions/dashboardState';
const propTypes = {
id: PropTypes.string,
parentId: PropTypes.string,
depth: PropTypes.number,
index: PropTypes.number,
renderHoverMenu: PropTypes.bool,
renderTabContent: PropTypes.bool,
onChangeTab: PropTypes.func,
component: componentShape.isRequired,
parentComponent: componentShape.isRequired,
createComponent: PropTypes.func.isRequired,
deleteComponent: PropTypes.func.isRequired,
updateComponents: PropTypes.func.isRequired,
handleComponentDrop: PropTypes.func.isRequired,
logEvent: PropTypes.func.isRequired,
directPathToChild: PropTypes.arrayOf(PropTypes.string),
directPathLastUpdated: PropTypes.number,
dashboardId: PropTypes.number.isRequired,
isComponentVisible: PropTypes.bool,
};
const defaultProps = {
directPathToChild: [],
directPathLastUpdated: 0,
isComponentVisible: true,
};
function mapStateToProps(
{ dashboardLayout: undoableLayout, dashboardState, dashboardInfo },
ownProps,
) {
const dashboardLayout = undoableLayout.present;
const { id, parentId } = ownProps;
const component = dashboardLayout[id];
const props = {
component,
dashboardLayout,
parentComponent: dashboardLayout[parentId],
editMode: dashboardState.editMode,
undoLength: undoableLayout.past.length,
redoLength: undoableLayout.future.length,
filters: getActiveFilters(),
directPathToChild: dashboardState.directPathToChild,
activeTabs: dashboardState.activeTabs,
directPathLastUpdated: dashboardState.directPathLastUpdated,
dashboardId: dashboardInfo.id,
fullSizeChartId: dashboardState.fullSizeChartId,
};
// rows and columns need more data about their child dimensions
// doing this allows us to not pass the entire component lookup to all Components
if (component) {
const componentType = component.type;
if (componentType === ROW_TYPE || componentType === COLUMN_TYPE) {
const { occupiedWidth, minimumWidth } = getDetailedComponentWidth({
id,
components: dashboardLayout,
});
if (componentType === ROW_TYPE) props.occupiedColumnCount = occupiedWidth;
if (componentType === COLUMN_TYPE) props.minColumnWidth = minimumWidth;
}
}
return props;
}
function mapDispatchToProps(dispatch) {
return bindActionCreators(
{
addDangerToast,
createComponent,
deleteComponent,
updateComponents,
handleComponentDrop,
setDirectPathToChild,
setFullSizeChartId,
setActiveTabs,
logEvent,
},
dispatch,
);
}
function tasking(depth, index) {
let time = (depth - 2) * 10 + index * 1000;
// console.log(time)
return new Promise((resolve, reject) => {
setTimeout(() => {
// console.log('弹出队列');
resolve()
}, time)
})
}
class DashboardComponent extends React.PureComponent {
state = {
isLoading: false
}
async componentWillMount() {
if (this.props.component && this.props.component.children && this.props.component.children.length >= 2) {
await tasking(this.props.depth, this.props.index);
}
this.setState({
isLoading: true
})
}
render() {
const { component } = this.props;
const Component = component ? componentLookup[component.type] : null;
return (Component && this.state.isLoading) ? <Component {...this.props} /> : <Loading />;
}
}
DashboardComponent.propTypes = propTypes;
DashboardComponent.defaultProps = defaultProps;
export default connect(mapStateToProps, mapDispatchToProps)(DashboardComponent);