反应瓶颈TextInput输入字段

时间:2019-06-30 13:46:34

标签: javascript reactjs performance redux

我这里有一个很大的React应用程序(与Redux一起使用),它有很大的瓶颈。

我们已经通过使用产品编号或产品名称实施了产品搜索,而这种搜索非常耗时。

问题:如果用户键入某些字符,则这些字符在InputField中的显示确实会延迟。 UI冻结了几秒钟。 在Internet Explorer 11中,搜索几乎无法使用。

这是用于过滤产品的Material UI TextField。

我已经进行了优化:

  1. 替换了 style = {{                     maxHeight:230,                     overflowY:“滚动”,                   }} const cssStyle = {..}
  2. 将一些关键组件从 React.Component 更改为 React.PureComponent
  3. 为我们的SearchComponent添加了 shouldComponentUpdate
  4. 删除了一些不必要的关闭绑定
  5. 删除了一些不必要的对象
  6. 删除了所有 console.log()
  7. 为输入字段添加了去抖(这使情况更糟)

这就是我们的SearchComponent当前的样子:

import React, { Component } from 'react';
import PropTypes from 'prop-types';
import Downshift from 'downshift';

import TextField from '@material-ui/core/TextField';
import MenuItem from '@material-ui/core/MenuItem';
import Paper from '@material-ui/core/Paper';
import IconTooltip from '../helper/icon-tooltip';

import { translate } from '../../utils/translations';

const propTypes = {
  values: PropTypes.arrayOf(PropTypes.shape({})).isRequired,
  legend: PropTypes.string,
  helpText: PropTypes.string,
  onFilter: PropTypes.func.isRequired,
  selected: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
  isItemAvailable: PropTypes.func,
};

const defaultProps = {
  legend: '',
  helpText: '',
  selected: '',
  isItemAvailable: () => true,
};

const mapNullToDefault = selected =>
  (selected === null || selected === undefined ? '' : selected);

const mapDefaultToNull = selected => (!selected.length ? null : selected);

class AutoSuggestField extends Component {
  shouldComponentUpdate(nextProps) {
    return this.props.selected !== nextProps.selected;
  }

  getLegendNode() {
    const { legend, helpText } = this.props;
    return (
      <legend>
        {legend}{' '}
        {helpText && helpText.length > 0 ? (
          <IconTooltip helpText={helpText} />
        ) : (
          ''
        )}
      </legend>
    );
  }

  handleEvent(event) {
    const { onFilter } = this.props;

    const value = mapDefaultToNull(event.target.value);

    onFilter(value);
  }

  handleOnSelect(itemId, item) {
    const { onFilter } = this.props;
    if (item) {
      onFilter(item.label);
    }
  }

  render() {
    const { values, selected, isItemAvailable } = this.props;

    const inputValue = mapNullToDefault(selected);
    const paperCSSStyle = {
      maxHeight: 230,
      overflowY: 'scroll',
    };
    return (
      <div>
        <div>{this.getLegendNode()}</div>
        <Downshift
          inputValue={inputValue}
          onSelect={(itemId) => {
            const item = values.find(i => i.id === itemId);
            this.handleOnSelect(itemId, item);
          }}
        >
          {/* See children-function on https://github.com/downshift-js/downshift#children-function */}
          {({
            isOpen,
            openMenu,
            highlightedIndex,
            getInputProps,
            getMenuProps,
            getItemProps,
            ref,
          }) => (
            <div>
              <TextField
                className="searchFormInputField"
                InputProps={{
                  inputRef: ref,
                  ...getInputProps({
                    onFocus: () => openMenu(),
                    onChange: (event) => {
                      this.handleEvent(event);
                    },
                  }),
                }}
                fullWidth
                value={inputValue}
                placeholder={translate('filter.autosuggest.default')}
              />
              <div {...getMenuProps()}>
                {isOpen && values && values.length ? (
                  <React.Fragment>
                    <Paper style={paperCSSStyle}>
                      {values.map((suggestion, index) => {
                        const isHighlighted = highlightedIndex === index;
                        const isSelected = false;
                        return (
                          <MenuItem
                            {...getItemProps({ item: suggestion.id })}
                            key={suggestion.id}
                            selected={isSelected}
                            title={suggestion.label}
                            component="div"
                            disabled={!isItemAvailable(suggestion)}
                            style={{
                              fontWeight: isHighlighted ? 800 : 400,
                            }}
                          >
                            {suggestion.label}
                          </MenuItem>
                        );
                      })}
                    </Paper>
                  </React.Fragment>
                ) : (
                  ''
                )}
              </div>
            </div>
          )}
        </Downshift>
      </div>
    );
  }
}

AutoSuggestField.propTypes = propTypes;
AutoSuggestField.defaultProps = defaultProps;

export default AutoSuggestField;
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.5.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.5.0/umd/react-dom.production.min.js"></script>

似乎我没有发现性能问题,因为它仍然存在。有人可以帮忙吗?

0 个答案:

没有答案