Я принял пример TodoList, чтобы отразить мою проблему, но, очевидно, мой код в реальном мире более сложный.React performance: рендеринг большого списка с PureRenderMixin
У меня есть такой псевдокод.
var Todo = React.createClass({
mixins: [PureRenderMixin],
............
}
var TodosContainer = React.createClass({
mixins: [PureRenderMixin],
renderTodo: function(todo) {
return <Todo key={todo.id} todoData={todo} x={this.props.x} y={this.props.y} .../>;
},
render: function() {
var todos = this.props.todos.map(this.renderTodo)
return (
<ReactCSSTransitionGroup transitionName="transition-todo">
{todos}
</ReactCSSTransitionGroup>,
);
}
});
Все мои данные неизменяемы, и PureRenderMixin используется надлежащим образом, и все работает нормально. Когда данные Todo изменяются, повторно отображается только родительский и отредактированный todo.
Проблема в том, что в какой-то момент мой список растет, когда пользователь прокручивается. И когда обновляется один Todo, требуется все больше и больше времени для рендеринга родителя, вызовите shouldComponentUpdate
на всех тодосах, а затем визуализируйте одиночное todo.
Как вы можете видеть, компонент Todo имеет другой компонент, отличный от данных Todo. Это данные, которые необходимы для рендеринга всеми todos и являются общедоступными (например, мы могли предположить, что для todos есть «displayMode»). Наличие многих свойств делает работу shouldComponentUpdate
немного медленнее.
Кроме того, с помощью ReactCSSTransitionGroup
кажется замедлить немного тоже, как ReactCSSTransitionGroup
должны оказывать себя и ReactCSSTransitionGroupChild
еще до shouldComponentUpdate
из несделанного называется. React.addons.Perf
показывает, что рендеринг ReactCSSTransitionGroup > ReactCSSTransitionGroupChild
- это время, потраченное впустую для каждого элемента списка.
Итак, насколько я знаю, я использую PureRenderMixin
, но с большим списком этого может быть недостаточно. Я по-прежнему получаю не очень плохие представления, но хотел бы знать, есть ли простые способы оптимизации моих рендерингов.
Любая идея?
Edit:
До сих пор мой большой список разбивается на страницы, так что вместо того, чтобы иметь большой список вещей, я теперь разделить этот большой список в списке страниц. Это позволяет иметь лучшие характеристики, поскольку каждая страница может теперь реализовать shouldComponentUpdate
. Теперь, когда элемент изменяется на странице, React должен вызывать основную функцию рендеринга, которая выполняет итерацию на странице, и вызывать функцию рендеринга только с одной страницы, что делает работу с меньшим количеством итераций.
Тем не менее, мои показатели рендера по-прежнему линейны для номера страницы (O (n)) У меня есть. Так что, если у меня тысячи страниц, это все равно та же проблема :) В моем случае, это вряд ли произойдет, но меня все еще интересует лучшее решение.
Я уверен, что можно достичь производительности рендеринга O (log (n)), где n - количество элементов (или страниц), путем разбиения большого списка на дерево (например, постоянная структура данных) и где каждый узел имеет возможность короткого замыкания вычисления с shouldComponentUpdate
Да, я имею в виду что-то похожее на постоянные структуры данных, как вектор в Scala или Clojure:
Однако я м обеспокоены реакцией, потому что, насколько я знаю, возможно, потребуется создать промежуточный дом узлов при рендеринге внутренних узлов дерева.Это может быть проблемой в соответствии с usecase (and may be solved in future versions of React)
Также, поскольку мы используем Javascript, мне интересно, поддерживает ли Immutable-JS это и делает доступными «внутренние узлы». См: https://github.com/facebook/immutable-js/issues/541
Edit: полезные ссылки с моими экспериментами: Can a React-Redux app really scale as well as, say Backbone? Even with reselect. On mobile
Сначала нам нужно определить «большой», и после этого нам нужно понять, что чем больше элементов, вставленных в DOM, тем медленнее производительность. В сочетании с переходами CSS вы ожидаете более медленную производительность в целом. Также PureRenderMixin будет работать только в том случае, если контент, который вы визуализируете, постоянно _exact_. –
Используете ли вы 'ключ' для своих' Тодо'? –
Вы найдете это полезным. http://stackoverflow.com/questions/34983963/performance-issue-with-react – user730009