Skip to content

MUC Sidebar optimization in case of massive room joins. #3302

@JohnXLivingston

Description

@JohnXLivingston

Describe the bug

Hello,

Hi. I'm currently doing some performance tests on ConverseJS. I'm using it in a chat plugin for Peertube (a streaming platform). There are some specific use cases for such platforms, that are not very "standard" in the XMPP world. For example, there can be a lot of users joining at the exact same time (when a live starts). So i have developed some stress tests tools, to find bottlenecks, and to try to fix them.

Currently, i'm evaluating the impact of massive joins, massive nick changes (in my case, users join the room as "Anonymous 12345", then have to change their nickname), then massive leavings.

In this situation, one of the high CPU usage cause is the MUC sidebar rendering. It will be rendered multiple time: when a user joins, when a user change nick, when vcard are downloaded, ...
So, if 100 users joins in a few seconds, the participant list in the sidebar will be rendered continuously, blocking the browser.

I have a fix that seems to help a lot: just use lodash.debounce around the sidebar re-rendering.

Would such fix be welcome in ConverseJS upstream?
I will submit a PR with my fix, and let you decide if you want to merge it or not (if not, i can manually patch, this is not an issue for me).

To Reproduce
Steps to reproduce the behavior:

  1. Join a room using ConverseJS
  2. Massively join the room with bots
  3. See the browser load.

Screenshots

I have some stress test tools. Here are 2 CPU usage graph: one with ConverseJS v10.1.6, one with the fix i suggest.

Note: there are some other tweaking in my code. For example, i hide join/leave notifications, and some nick changes.

In this test scenario, there are 3 key times:

  • 100 bots are joining the room
  • the 100 bots are changing their nicknames
  • the 100 bots are leaving the room
Before patch After patch
image image

As you can see, there is a much lower CPU usage with the patch (please notice the vertical scale change).

For the record, here is the patch that i applied in the above test:

diff --git a/src/plugins/muc-views/sidebar.js b/src/plugins/muc-views/sidebar.js
index 16688c0..dadf325 100644
--- a/src/plugins/muc-views/sidebar.js
+++ b/src/plugins/muc-views/sidebar.js
@@ -2,7 +2,7 @@ import 'shared/autocomplete/index.js';
 import tplMUCSidebar from "./templates/muc-sidebar.js";
 import { CustomElement } from 'shared/components/element.js';
 import { _converse, api, converse } from "@converse/headless/core";
-
+import debounce from 'lodash-es/debounce.js';
 import 'shared/styles/status.scss';
 import './styles/muc-occupants.scss';
 
@@ -19,11 +19,12 @@ export default class MUCSidebar extends CustomElement {
     connectedCallback () {
         super.connectedCallback();
         this.model = _converse.chatboxes.get(this.jid);
-        this.listenTo(this.model.occupants, 'add', () => this.requestUpdate());
-        this.listenTo(this.model.occupants, 'remove', () => this.requestUpdate());
-        this.listenTo(this.model.occupants, 'change', () => this.requestUpdate());
-        this.listenTo(this.model.occupants, 'vcard:change', () => this.requestUpdate());
-        this.listenTo(this.model.occupants, 'vcard:add', () => this.requestUpdate());
+        const debouncedRequestUpdate = debounce(() => this.requestUpdate(), 200, {maxWait: 1000})
+        this.listenTo(this.model.occupants, 'add', debouncedRequestUpdate);
+        this.listenTo(this.model.occupants, 'remove', debouncedRequestUpdate);
+        this.listenTo(this.model.occupants, 'change', debouncedRequestUpdate);
+        this.listenTo(this.model.occupants, 'vcard:change', debouncedRequestUpdate);
+        this.listenTo(this.model.occupants, 'vcard:add', debouncedRequestUpdate);
         this.model.initialized.then(() => this.requestUpdate());
     }

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions