node.js - 使用 React 和 Socket.io 的聊天应用程序在发送太多消息后挂起
问题描述
我的基本聊天应用程序在发送大约 7 条消息后变得非常缓慢,尽管它在只发送几条消息时确实有效。
我在返回的组件中放置了一个打印语句。我注意到每次提交聊天消息时,打印语句的调用次数都是以前的两倍。我假设我的应用程序变得越来越慢,因为我发送更多消息时必须以指数方式重新渲染 DOM。
有没有人知道为什么会这样?
这是我的反应应用
import React from 'react';
import io from "socket.io-client";
let socket = io.connect("localhost:8080");
function App() {
const [curMessage, setMessage] = React.useState({name: "", message: ""});
const [messageList, setList] = React.useState([]);
socket.on("receiveMsg", message => {
setList([...messageList, message]);
});
function handleTyping(e) {
let target = e.target;
if (target.id === "name") {
setMessage({...curMessage, name: target.value});
} else {
setMessage({...curMessage, message: target.value});
}
}
function handleSubmit(e) {
e.preventDefault();
setList([...messageList, curMessage]);
setMessage({name: "", message: ""});
socket.emit("message", curMessage);
}
return (
<div>
<form onSubmit={handleSubmit}>
<input id="name" onChange={handleTyping} value={curMessage.name}></input>
<input id="message" onChange={handleTyping} value={curMessage.message}></input>
<button>Send Message</button>
</form>
<ul>
{messageList.map(msg => {
return <li> {msg.name} {msg.message} </li>
})}
{console.log("test")}
</ul>
</div>
);
}
export default App;
这是我的服务器端代码(虽然我认为这段代码很好)
const express = require("express");
const app = express();
const http = require("http").createServer(app);
const io = require("socket.io")(http);
http.listen(8080, () => console.log("Connected to Server"));
io.on("connection", socket => {
console.log("User has connected " + socket.id);
socket.on("message", data => {
socket.broadcast.emit("receiveMsg", data);
});
});
解决方案
尽量把你socket.on(..)
里面的useEffect。也许在渲染中执行 setState 是导致速度变慢的原因。
useEffect(() => {
socket.on("receiveMsg", (message) => {
setList([...messageList, message]);
});
return () => {
socket.off("receiveMsg");
};
}, [messageList]);
推荐阅读
- cassandra - 当我在备份目录中有大量文件时,恢复 Cassandra 增量备份的过程是什么
- html - 如何在这里调整我的身材的大小?
- css - 溢出:自动与 flex 导致滚动条重叠内容
- angular - 禁用 NgbTypehead 的多个实例
- sql - SQL query for user input
- google-apps-script - 如何将元素转换为与第一个选定元素相同的大小?
- python - pyspark 在 1 节点和 2 节点集群上的连接数据性能(混洗数据)
- xslt-1.0 - 如何删除字符串中的重复字符?
- objective-c - 第二个 animateWithDuration 调用禁用动画
- php - laravel 数据库通知存储 url 添加 \\ 到 //