【问题标题】:Redux performance with large objects大对象的 Redux 性能
【发布时间】:2017-07-27 18:25:52
【问题描述】:

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

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

应用结构

我的应用程序的结构是 settings(小 json)、results(大 json)和 calculate(settings)。计算是确定性和幂等的。我的应用以图表、表格等形式呈现设置元数据和结果。

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

Redux 行为和潜在解决方案

当我在我的商店中包含结果时,我的应用程序很慢:

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

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

当我引用但不在我的商店中包含结果时,我的应用程序很快:

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 建议不要存储函数,因此另一种方法是使用字符串保存引用...类似于:

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);
}

将大数据保存在存储之外是可行的,但似乎有更好的方式 react 支持这个用例。

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

【问题讨论】:

    标签: javascript json performance reactjs redux


    【解决方案1】:

    简单地“将值保存到存储中”不会影响速度。这就是您在 reducer 中处理这些值并在 UI 中使用它们的方式。所以,给出具体建议有点困难,因为你没有提供任何关于你如何实际使用这些数据的信息。

    一般来说,根据其他评论,使用记忆选择器(由 Reselect 库创建)仅有助于在输入实际发生变化时重新计算昂贵的派生值。

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

    【讨论】:

    • 谢谢。这些资源非常有用!我将研究如何处理我的数据。我怀疑在某个地方我不小心触发了遍历几个较大对象的浅层相等检查。
    【解决方案2】:

    试试Reselect。每次计算后结果对象引用是否发生变化?如果是这样的话,这个小图书馆应该可以帮到你。

    【讨论】:

    • 是的,大多数计算后结果都会发生变化。
    • 如果您的结果是计算出来的并且取决于其他状态属性,我建议使用选择器而不是将结果存储在存储中。重新选择我链接的库,可以提高性能,因为它只会在输入发生变化时重新计算(在你的情况下 - 设置)。
    • 计算不是性能瓶颈。我很少在必要时重新计算。
    • 计算本身可能不是瓶颈,但结果对象引用的变化可能会。如果是这样,请不要将结果保存在商店本身。见link
    猜你喜欢
    • 1970-01-01
    • 2020-03-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-20
    • 2019-12-07
    • 1970-01-01
    • 2019-11-06
    相关资源
    最近更新 更多