Reputation: 131
i'm implementing chatting feature with realtime database of Firebase and React, and i wrote like this:
useEffect(() => {
messagesListeners(pid)
}, [])
const messagesListeners = async (pid: string) => {
const messages = [];
realtimeService
.ref(`messages/post-${pid}`)
.on('child_added', DataSnapshot => {
messages.push(DataSnapshot.val())
setComments([...messages])
})
}
but it's making browser's CPU skyrocketing. i think it's because of the part of "setComments". when i removed that part (setComments), this issue doesn't happen. if there are 100 of comments, that set comments 100 times.
How can i bring new comments without CPU's skyrocketing?
Upvotes: 0
Views: 59
Reputation: 598728
The problem is in here::
setComments([...messages])
This call, adds your entire messages
array to the end of the existing comments
array. This leads to an exponentially growing comments
array:
child_added | messages | comments |
---|---|---|
one | [one] | [one] |
two | [one,two] | [one,one,two] |
three | [one,two,three] | [one,one,two,one,two,three] |
four | [one,two,three,four] | [one,one,two,one,two,three,one,two,three,four] |
five | [one,two,three,four,five] | [one,one,two,one,two,three,one,two,three,four,one,two,three,four,five] |
... |
So the minimal fix is to set the comments
array to the messages
, instead of constantly appending:
setComments(messages)
You can also reduce the number of calls to setComments
by listening to a value
event, instead of child_added
. The value
event will fire only once for all comments, which you can then process with:
const messagesListeners = async (pid: string) => {
realtimeService
.ref(`messages/post-${pid}`)
.on('value', snapshot => {
const messages = [];
snapshot.forEach((child) => {
messages.push(child.val())
});
setComments(messages)
})
}
Upvotes: 1