【问题标题】:Redux dispatch action taking too long despite reducer function attached executes fast尽管附加的 reducer 函数执行速度很快,但 Redux 调度操作花费的时间太长
【发布时间】:2021-12-26 00:49:53
【问题描述】:

我收到 setTimeout handler took 500+ ms 类型的 chrome 违规错误,这些错误严重阻塞了我的应用程序,并且每次附加到 websocket 有效负载的操作出现并被处理时都会发生一些错误。我尝试使用 chrome profiler 对其进行调试,这正是它在处理有效负载时所显示的内容。

https://imgur.com/a/ZnS0ZlG

(anonymous) 函数是 reducer 中的函数,运行时间与错误一致。

这是一些代码。

// ACTION
const someAction = (data): Thunk => async dispatch => {
  try {
    const t = performance.now();
    dispatch(someAction(data));
    console.log('after dispatching cellReceived', performance.now() - t); 
    // logs 800+ ms and is consistent with chrome violation errors (setTimeout handler took <N> ms
  }
}

// REDUCER
  export default(state: State, action: Actions) {
  switch(action.type) {
    ...
    case ActionType.someAction: {
      const { data } = action.payload;
      const t = performance.now();
      (... do calculations here)
      console.log(performance.now() - t) // logs 30ms
    }
  }
}

我将非常感谢任何帮助,这周我必须花费 20 多个小时来阅读此问题并尝试对其进行调试。我没有找到任何关于如何使用 chrome 的分析器正确调试的好资源。

【问题讨论】:

  • 在 devtools 设置中启用 V8 stats and all events:可能是一些内部函数,如 JSON.stringify 等。
  • @wOxxOm 我仍然没有看到任何相关内容,但我必须再说一遍,我并不是分析器工具方面的专家。
  • @wOxxOm imgur.com/a/ZnS0ZlG 我用更多信息更新了 imgur,onMessageListener 是附加到 message 处理程序的组件中的函数,它使用 mqtt.js 设置 Web 套接字功能
  • 如果没有看到完整的调用堆栈就不可能猜到,所以就像我已经假设它可能正在序列化数据以便发送它们。
  • @wOxxOm 我使用这篇文章来查看我是否获得了有关实际运行的函数的更多信息。 v8.dev/docs/rcs 我不知道我做错了什么,这是我按照以下步骤看到的:imgur.com/a/MiGH7cL 而在文档中,您实际上可以看到正在运行的函数

标签: performance redux react-redux google-chrome-devtools


【解决方案1】:

它实际上不需要是 dispatch 或 reducer。在某些情况下,React 将同步启动重新渲染,这是 dispatch 的直接结果 - 所以在您的 console.log('after dispatching cellReceived', performance.now() - t); 行之前

所以这也可能是一个非常慢的 React 渲染。

如果您想确定:

import { batch } from 'react-redux'

const someAction = (data): Thunk => async dispatch => {
  try {
    batch(() => {
        const t = performance.now();
        dispatch(someAction(data));
        console.log('after dispatching cellReceived', performance.now() - t); 
    })
  } catch {/*...*/}
}

【讨论】:

  • 我实际上认为这是一个非常缓慢的重新渲染,我使用 nivo - 一个反应图表库 - 用实时数据渲染大约 30 个图表,结果证明它不是这个用途的最佳库case 毕竟我不知道为什么会出现这种错误,但现在说得通了,svgs 的渲染可能使用了一些导致强制布局/重排的方法。无论如何,我发现在界面上将更多更新一起批处理更容易,所以现在我只批处理 10 个更新,而不是每次更新 10 次 - 临时解决方案,但效果更好。
猜你喜欢
  • 1970-01-01
  • 2020-06-21
  • 1970-01-01
  • 1970-01-01
  • 2015-11-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多