【问题标题】:React app gets slow renders slow after emitting socketio message发出 socketio 消息后,React 应用程序变得缓慢渲染缓慢
【发布时间】:2018-05-20 11:22:09
【问题描述】:

我有一个反应应用程序。该代码确实可以完美运行,但在使用它之后。它开始变慢。稍等片刻即可再次使用。

当你按下按钮时,我使用 socketio 发出消息。

多次使用后函数调用耗时较长。

函数调用是websocket.js 的一部分。但是,当您深入研究函数时,似乎反应渲染需要更长的时间。

需要大量时间的函数。

所以 react 需要很多时间来渲染视图。我只能认为我不会删除会占用大量内存并因此减慢渲染过程的内容。在图片上您看到它在文件react-dom.development.js 中,在为生产构建时也会出现此问题。

import React, { Component } from 'react';
import Card from './Card.js'

class Game extends Component {
  constructor(props) {
    super(props);
    this.state = {
      socket: this.props.socket,
      card: {
        "name": "",
        "cardValues": {}
      }
    }
    this.props.socket.emit("startGame");
  }
  render() {
    let {socket, card} = this.state;
    socket.on("startGame", (data) => this.setState({
        card: data["card"],
    }))
    socket.on("nextCard", (data) => this.setState({
        card: data["nextCard"],
    }))
    return (
      <div className="Game">
          <p>GAME</p>
          <Card socket={socket} card={this.state.card}/>
      </div>
    );
  }
}
export default Game;

这部分使用Card类。

import React, { Component } from 'react';

class Card extends Component {
  constructor(props) {
    super(props);
    this.state = {
      socket: this.props.socket,
    }
  }

  chooseCardValue = (value) => {
      this.state.socket.emit("chooseCard", {"cardValue": value});
  }

  render() {
    let card = this.props.card;
    return (
      <div className="Card">
          <h3 className="Country">{card["name"]}</h3>
          <ul>
            {
              Object.keys(card["cardValues"]).map((value, i) => {
                return <li key={i}><button onClick = {
                    this.chooseCardValue.bind(null, value)
                }>{value}: {card["cardValues"][value]}</button></li>
              })
            }
          </ul>
      </div>
    );
  }
}
export default Card;

在这里定义按钮。当你点击按钮时,它会触发函数chooseCardValue,随着时间的推移会变慢。

为什么会变得这么慢,是什么原因?

我试图只包含可能相关的部分。为了以防万一,整个课程都可以在这里找到:https://lpaste.net/3474101090415280128

【问题讨论】:

  • 有人对我的问题投了反对票。我不知道为什么,非常感谢您的反馈,所以我知道我可以做些什么来改进我的问题。
  • 我不知道为什么这个问题被否决了,这是一个非常详细的问题,有很好的例子。我一直在寻找这个,你的问题让我找到了答案。谢谢

标签: javascript reactjs rendering


【解决方案1】:

您正在将套接字侦听器附加到渲染方法中。这意味着每次您的应用重新渲染时,您都会添加 2 个额外的侦听器。此外,在您调用setState 的侦听器内部,这会触发重新渲染,从而添加另一个侦听器。

当您第一次收到消息时,您的应用将呈现一次,并添加一个侦听器。 第二次收到消息时,您的应用将呈现两次(每个侦听器一次),您将添加 2 个侦听器。 第三次将有 4 次渲染。 然后是 8、16、32 等等。

基本上你需要做的不是在渲染方法中添加那些监听器。您可以尝试将它们移至 constructorcomponentDidMount 方法,但实际上它应该位于组件树之外的某个位置。

为了清楚起见,这些是我所说的:

let {socket, card} = this.state;
socket.on("startGame", (data) => this.setState({
    card: data["card"],
}))
socket.on("nextCard", (data) => this.setState({
    card: data["nextCard"],
}))

【讨论】:

  • 所以所有的socket.on 事件都应该在componentDidMount 中或者在远离组件的不同文件中?如果您知道任何这样做的示例,我很高兴知道。
  • 另外:这里的这个例子是否也被认为是“坏的”:github.com/vlw0052/React-Chat-App/blob/master/src/components/… 或者为什么在这种特殊情况下可以这样做?
猜你喜欢
  • 2019-06-28
  • 1970-01-01
  • 1970-01-01
  • 2020-12-06
  • 1970-01-01
  • 2018-07-18
  • 1970-01-01
  • 2019-11-13
  • 2021-06-04
相关资源
最近更新 更多