Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Timeline performance #516

Open
Caellian opened this issue Dec 1, 2023 · 0 comments
Open

Timeline performance #516

Caellian opened this issue Dec 1, 2023 · 0 comments

Comments

@Caellian
Copy link

Caellian commented Dec 1, 2023

Web UI timeline performance it horrific when rendering a lot of tiny events.

The reason why is because SVG is being used to display them and there's clipping on every event to avoid text overflow.
SVG is cool and besides interactivity possibly causing some issues for Safari users, it's a much simpler solution than drawing stuff on the canvas.

But the overflow: hidden attribute prevents the browser from batch rendering which means that when there's (let's assume) 1000 2px-wide events, their text requires 1000 individual render calls and the one containing event grid has to wait for all of them which means each animation frame has to deal with a lot of render calls and produces textures that are basically discarded in the last pass due to padding. Browsers do parallelize these draw calls, but it's impossible to do it for 1000 components so this causes

  • a) a lot of pointless data transfers,
  • b) if 50 components are drawn in parallel, 1000/50 sequential draw calls.

A very simple solution to this is not displaying vis-item-overflow at all if it's width is smaller than vis-item-content padding. I'd personally skip it if vis-item-content is less wide than padding + 2ch too because 2ch is too little to be useful IMO.
Also, vis-item-content has transform: translateX(0);, not sure of this is intentional, but this introduces additional pipeline complexity for all 1000 of the invisible draw calls.

My suggestion is that events get grouped into groups based on their duration and that the timeline hides content of individual events at certain scales.

This can be achieved globally via CSS properties and classes to avoid huge DOM updates:

.ev-len-1min,
.ev-len-5min,
.ev-len-10min,
.ev-len-20min
  display: none

.timline-data-very-zoomed-out .ev-len-20min
  display: initial
.timline-data-zoomed-out .ev-len-10min
  display: initial
.timline-data-zoomed .ev-len-5min
  display: initial
.timeline-data-zoomed-in .ev-len-1min
  display: initial

Names are verbose for clarity, better names should be used :)

With this approach, on zoom in/out, only the class of the timeline needs to be updated. The browser would then discard all 1000 draw calls instead of drawing and then cropping them into transparent 2px wide rects and trying to composit them together.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant