High browser CPU & memory usage

Hi, we are facing “high” Chrome CPU usage in our application.

When logging into the app, the CPU and memory usage seems normal, but while using the app for some minutes straight, the CPU increase to 10 - 40% (in chrome task manager, resulting in 5 - 17% in windows task manager). (all values when doing no interaction with website)
Further the “memory footprint” is increase in this time endlessly up to 1.5 - 2 GB usage, while the “JS memory” stays within 80 - 200 MB.
This is much more than our Vaadin 8 application and we would expect performance problems with low end hardware.

image

When investigating the performance in chrome dev tool we see there is a recursive Timeout scheduled for generating MenuBar items. This issue occurred since Vaadin 14 but meanwhile we are on 24.5.11 and now ready to ship to production.

Do you need more info? Any advice or solution would be highly appreciated!

Call Tree:
image

chunk-[…].js

function Ytt(s, e) {
    if (s.$connector)
        return;
    const t = new MutationObserver(i => {  [...] });
    s.$connector = {
        generateItems(i) {
            if (!s.shadowRoot) {
                setTimeout( () => s.$connector.generateItems(i));
                return
            }
            if (!s._container) {
                queueMicrotask( () => s.$connector.generateItems(i));
                return
            }
            i && (s.__generatedItems = window.Vaadin.Flow.contextMenuConnector.generateItemsTree(e, i));
            let n = s.__generatedItems || [];
            n.forEach(o => {
                o.disabled = o.component.disabled,
                o.component._rootItem = o
            }
            ),
            n.forEach(o => {
                t.observe(o.component, {
                    attributeFilter: ["hidden", "disabled"],
                    attributeOldValue: !0
                })
            }
            ),
            n = n.filter(o => !o.component.hidden),
            s.items = n,
            s._buttons.forEach(o => {
                o.item && o.item.component && o.addEventListener("click", r => {
                    r.composedPath().indexOf(o.item.component) === -1 && (o.item.component.click(),
                    r.stopPropagation())
                }
                )
            }
            )
        }
    }
}

Ytt is called here:

window.Vaadin.Flow.menubarConnector = {
    initLazy: Ytt,
    setClassName: Ztt
};

I recommend creating a GitHub issue with a standalone code example that reproduces this behavior: GitHub · Where software is built

Have you checked if the client is spamming the server with events?
If so, you might be able to find out when the spamming starts and find the root cause.

I had an issue a couple of days ago where:

  • I have a TextField filter above a TreeGrid
  • When I filter the TreeGrid I open all parent entries
  • When the user clears the filter I close all parent entries again. This could trigger a never-ending stream of events to the server

Knowing that, I could investigate what I was doing that might trigger this.
I found that for some reason I did treeGrid.open/collapse(<list of all parent entries>)
When I switched to treeGrid.open/collapseRecursively(<root folders>, 99) the problem went away.

So, some sort of bug in TreeGrid, but I also did something dumb.