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

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.