大对象的Redux性能

问题描述:

我正在使用Redux和React构建一个Web应用程序.我的应用程序是一个分析应用程序,可呈现大量数据.我的商店很大时,我遇到了性能问题.

I am using Redux and React to build a web application. My application is an analytics application that renders a lot of data. I am running into performance issues when my store becomes large.

避免在Redux中处理大数据的性能问题的首选方法是什么?

What is the preferred way of avoiding performance issues with large data in redux?

我的应用的结构使我具有settings(小json),results(大json)和calculate(settings).计算是确定性和幂等的.我的应用程序在图形,表格等中呈现设置元数据和结果.

My app is structured in a way where I have settings (small json), results (large json), and calculate(settings). Calculate is deterministic and idempotent. My app renders settings metadata and the results in graphs, tables, etc.

因为计算是确定性和幂等的,所以我知道当设置不变时结果也不会改变.设置更改后,我的结果可能会更改.换句话说,我可以仅依靠设置来确定是否需要更新UI.

Because calculate is deterministic and idempotent, I know results will not change when settings does not change. When settings do change my results may change. In other words, I'm comfortable relying on only settings to determine if I need to update my UI.

当我在商店中添加结果时,我的应用程序运行缓慢:

My application is slow when I include results inside my store:

let settings = { foo: "bar" };
let results = calculate(settings);
Object.assign({}, state, { settings: settings, results: results });

//deterministic and idempotent
function calculate(settings) {
  return /*large json*/;
}

引用时我的应用程序运行很快,但商店中未包含结果:

My application is fast when I reference but don't include results inside my store:

let settings = { foo: "bar" };
let results = calculate(settings);
Object.assign({}, state, { settings: settings, results: () => results });

//deterministic and idempotent
function calculate(settings) {
  return /*large json*/;
}

我知道redux建议不要存储函数,因此一种替代方法是使用字符串来保存引用...之类的东西

I know redux advises against storing functions, so an alternative is to save a reference using a string...something like:

let settings = { foo: "bar" };
let calculationId = uuid(); //could also be a hash of settings if I want to avoid some false positive UI re-rendering
let results = calculate(settings);
setResults(calculationId, results);
Object.assign({}, state, { settings: settings, calculationId: calculationId });

//deterministic and idempotent
function calculate(settings) {
  return /*large json*/;
}

let fakeStore = { calculationId: null, results: null };

function setResults(calculationId, results) {
  fakeStore. calculationId = calculationId;
  fakeStore.results = results;
}

function getResults(calculationId) {
  if(fakeStore.calculationId === calculationId) {
    return fakeStore.results;
  }
  throw new Error("Invalid data access");
}

render() {
  let calculationId = this.props.calculationId;
  let results = getResults(calculationId);
}

将大型数据存储在存储区之外是可行的,但是似乎有更好的方法可以响应以支持该用例.

Keeping large data outside of the store is tenable, but it seems like there may be better ways react supports this use case.

使用redux 3.7.1,react 15.4.2,react-redux 4.4.8

Using redux 3.7.1, react 15.4.2, react-redux 4.4.8

仅将值保存到存储中"将不会影响速度.这是您在化简器中处理的值并在您的UI中使用的重要方式.因此,由于您尚未提供有关如何实际使用该数据的任何信息,因此很难给出具体建议.

Simply "saving values into the store" will not affect speed whatsoever. It's how you process those values in your reducers, and use them in your UI that matter. So, it's a bit hard to give specific advice, since you haven't given any info on how you're actually using that data.

通常,根据其他评论,使用记忆选择器(由Reselect库创建)仅在输入实际更改时才重新计算昂贵的派生值很有帮助.

In general, per the other comment, use of memoized selectors (created by the Reselect library) is helpful for only recalculating expensive derived values when the inputs actually change.

有关改善Redux使用性能的更多信息,请参阅:

For more information on improving Redux usage performance, please see:

  • The Redux FAQ entry on scaling and performance
  • The Redux Performance section of my React/Redux links list
  • My blog post Practical Redux, Part 6: Connected Lists, Forms, and Performance