vaadin / web-components

A set of high-quality standards based web components for enterprise web applications. Part of Vaadin 20+
https://vaadin.com/docs/latest/components
453 stars 83 forks source link

Avatar group not performant #6282

Open danielvanmil opened 1 year ago

danielvanmil commented 1 year ago

Description

We render a lot (> 200) of avatar groups in a calendar overview which makes the component slow (rendering takes over 5 seconds) Some performance analysis lead us to the avatar group performance, see screen Performance insights:

image

Expected outcome

Faster rendering

Minimal reproducible example

Pseudo Storybook code:

const items = new Array(500).fill(1);

// Renderer for the story
const render = ({}: Partial<SidebarProps>): TemplateResult =>
  html`
    ${items.map(
      (_y) =>
        html`
          <vaadin-avatar-group
            .items=${[
              {name: "XXX", colorIndex: 1, abbr: "xxx", withTooltip: false},
              {name: "yyy", colorIndex: 2, withTooltip: false},
            ]}
          ></vaadin-avatar-group>
        `
    )}
  `;

Steps to reproduce

See example

Environment

Vaadin version(s): 24.1.4 OS: -

Browsers

Chrome

web-padawan commented 1 year ago

Thanks for the issue. The problem appears to be related to how vaadin-avatar-group calculates whether to show the overflow avatar. There might be some room for improvement related to DOM measurements.

In general, it's recommended to use vaadin-virtual-list to avoid rendering all the elements at once. I'm pretty sure that you'll also face the same issue when rendering e.g. 200 text-field components etc.

danielvanmil commented 1 year ago

Thanks @web-padawan. Our use case is to view a calendar with cards which already uses lazy loading, but in batches of for example 200 calendar items which isn't that much. Each card renders an avatar group. A virtual list is not the proper solution here.

danielvanmil commented 1 year ago

@web-padawan :

Would it be good to know why for example the tooltip calculations are that expensive as they are/can used everywhere? Without the (more expensive) overflow calculations it should be easy to render +/- 500 items or am I missing something.

Furthermore we often use the avatar-group in containers with a static width, so could it be an option to make the responsiveness optional and only look at the maxItemsVisible?

image

web-padawan commented 1 year ago

We should investigate if reducing some measurements is possible. For example, __setItemsInView() method is called in afterNextRender() on ready() and then also in _onResize() callback, which is apparently unnecessary.

danielvanmil commented 1 year ago

any plans to work on this (otherwise we have to find another solution)