首页 > 解决方案 > 发出 socketio 消息后,React 应用程序变得缓慢渲染缓慢

问题描述

我有一个反应应用程序。该代码确实可以完美运行,但在使用它之后。它开始变慢。等待一段时间后,您可以再次使用它。

当你按下一个按钮时,我使用 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

标签: javascriptreactjsrendering

解决方案


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

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

本质上,您需要做的不是在 render 方法中添加这些侦听器。您可以尝试将它们移至constructorcomponentDidMount方法,但实际上它应该位于组件树外部的某个位置。

为了清楚起见,这些是我正在谈论的行:

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

推荐阅读