Этот пост является продолжением пост об оптимизации производительности списков в приложении React .
Внимание.
В этом посте примеры были подготовлены специально для приложений Redux. Но сам подход можно применить и к другим библиотекам.
Совет ниже также работает в реакция-редукция версии 5 .
Мне не удалось добиться желаемого результата в версия 4 .
Я не вникал глубоко в причины.
Итак, стандартный способ хранения ряда элементов в приложении — это сохранение их в массиве:
Далее, скорее всего, где-то в вашем приложении будет компонент, отображающий этот список:const state = { targets: [{id: 'target1', radius: 10}, {id: 'target2', radius: 2}] };
const TargetsList = connect(state => ({targets: state.targets}))(
({ targets }) =>
<ul>
{ targets.map((target) => <TargetView key={target.id} target={target} />) }
</ul>
);
Если вдруг вам понадобится обновить один элемент, вам придется обновить весь массив (он неизменяемый):
function appReducer(state, action) {
if (action.type === 'UPDATE') {
return {
target: state.target.map((target) => {
if (target.id === action.id) {
return {
.
target,
radius: action.radius
};
} else {
return target;
}
})
}
}
// some other code
}
Также обновление элемента приведет к обновлению всего представления «TargetsList» (оно будет называться оказывать ).
Я сделал небольшая демонстрация с тестовым кодом для измерения производительности.
На моей машине обновление одного элемента в списке длиной 1000 занимает примерно 21 мс .
В предыдущий пост Я описал способ повышения производительности за счет использования дополнительных подписок для отслеживания изменений в дочернем компоненте, а также добавления некоторой логики в «shouldComponentUpdate» для компонента, отображающего список.
Но практически того же результата можно добиться, немного изменив форму данных.
Как оптимизировать?
Если вы используете github.com/reactjs/react-redux , то вы можете повысить производительность, изменив форму состояния на: const state = {
targetsOrder: ['id-1', 'id-2'],
targets: {
'id-1': { id: 'id-1', radius: 10 },
'id-2': { id: 'id-2', radius: 20 },
}
};
Далее вам нужно немного изменить компонент «TargetsList»:
const TargetsList = connect(state => ({targetsOrder: state.targetsOrder}))(
({ targetsOrder }) =>
<ul>
{ targetsOrder.map((id) => <TargetView key={id} targetId={id} />) }
</ul>
);
Обратите внимание, что в этом случае я передаю идентификатор элемента дочернему компоненту, а не весь элемент. Тогда «TargetView» не может быть «тупым компонентом» и должен подписываться на изменения состояния:
const TargetView = connect(
(state, ownProps) => ({target: state.targets[ownProps.targetId]})
)(({ target }) => {
// your render logic
return <Circle radius={target.radius} />;
});
Поскольку TargetView подписан на изменения состояния, он будет обновляться при обновлении своих данных.
Важно то, что «TargetList» НЕ БУДЕТ обновляться при изменении элемента в списке, поскольку «targetsOrder» остается прежним.
В некоторых случаях этот метод позволяет значительно повысить производительность.
→ Обновленное демо с измерениями Теперь обновление одного элемента на моей машине занимает 2,2 мс.
Это почти в 10 раз быстрее, чем в предыдущем примере.
Теги: #JavaScript #react #react.js #react.js #redux #веб-разработка #оптимизация производительности #производительность #производительность #производительность javascript #JavaScript #react.js
-
Google Предупреждает Себя (Appleoid #8)
19 Oct, 24 -
Arch Linux: Корневой Раздел На Samba
19 Oct, 24 -
Как Работает Фидо
19 Oct, 24