Тормозит приложение при наборе текста

Skywave

Есть приложение, использующее React в связке с Redux

Везде, где идет набор текста в input или textarea приложение начинает тормозить. Люди жалуются.

Почитал, что надо отключить devtools - отключил.

Дальше идут рекомментации по оптимизации shoultComponentUpdate, но тут надо обновлять каждый раз, т.к. каждая буква должна пропечататься.

Кто нибудь сталкивался с похожей проблемой? Может ли влиять на это размер состояния приложения? Состояние приложения объединяется из нескольких reducer'ов (7-8 штук) Каждый reducer может быть как Immutable.js объектом, так и простым js объектом.

На onChange вызывается один метод, который всплывает вверх по вложенным компонентам реакта на 3-4 уровня. Затем вызывается один экшн, который возвращает разу же объект, содержащий только name и value. Дальше один reducer его подхватывает и изменяет состояние через Immutable.setIn в одну строку.

Все происходит довольно плоско и я не знаю где можно оптимизировать. Помогите, пожалуйста, кто чем может.

2 ответа

Skywave

Попробуйте использовать uncontrolled компоненты. Изменение содержимого input не приводит к изменению состояния компонента, соответственно не вызывается лишний раз метод render(), при этом, буквы в input пропечатываются. А значение input доступно по ссылке this.input.value, и вы можете использовать его, например, при отправке формы.

class NameForm extends React.Component {
  constructor(props) {
    super(props);
    this.handleSubmit = this.handleSubmit.bind(this);
  }

  handleSubmit(event) {
    alert('A name was submitted: ' + this.input.value);
    event.preventDefault();
  }

  render() {
    return (
      <form onsubmit="{this.handleSubmit}">
        <label>
          Name:
           this.input = input} />
        </label>
        
      </form>
    );
  }
}


Skywave

Добавлю еще свой вариант.

Чтобы не напрягать redux, я записываю данные в state компонента через this.setState, а отправка в redux идет через задержку, либо по другому условию.

handleChange(e) {
    let self = this,
        event = {};

    // продолжаем извращаться
    for(var k in e) event[k]=e[k];

    let newState = {};
    for(var k in this.state) newState[k]=this.state[k];

    newState.field[event.target.name] = event.target.value;
    this.setState(newState);

    clearTimeout(this.changeTimeout);
    this.changeTimeout = setTimeout(function(){
        self.props.onChange(event, {
            name: event.target.name,
            value: event.target.value
        });
    }, 1000);
}

Попутно задам вопрос: Как можно оптимизировать этот код?

licensed under cc by-sa 3.0 with attribution.