vis-timeline icon indicating copy to clipboard operation
vis-timeline copied to clipboard

Initial render is extremely slow when options include start or end time

Open TheophileMot opened this issue 2 years ago • 6 comments

When the options object includes start or end, it takes second or two to load the timeline. This runs contrary to the documentation, which states that load time is sped up by including these parameters.

Minimal reproduction: https://codepen.io/theophilemot/pen/xxPMBBN

This loads two timelines, one with start and end, and the other without. Even though there is only a single item, it takes a second to render the first timeline.

Further examples can be seen in the official demos: compare this fast demo to this slow demo. Try refreshing the page on each of these; in the second case, the timeline takes a second or two to appear. (Again, it isn't the number of items that matters, but the presence of start/end.)

TheophileMot avatar Mar 04 '22 20:03 TheophileMot

I am also experiencing this issue. Curiously, the documentation states that adding a start and end will improve performance. I have tinkered with date formats, different ranges of time, dropping styling, no change. Adding either 'start', 'end', or both to my options will significantly reduce the initial render. My application behaves exactly as TheophileMot's fiddle above. Funny, I used the vis.js timeline several years back and don't remember this being an issue.

milopersic avatar Mar 15 '22 18:03 milopersic

I think it has to do with this check https://github.com/visjs/vis-timeline/blob/master/lib/timeline/Timeline.js#L215. Adding rollingMode to the options, even the default options, seems to provide a work around.

rollingMode: { follow: false },

TomHiller-swd avatar Aug 09 '22 17:08 TomHiller-swd

@TomHiller-swd Adding rollingMode as indicated does seem to mitigate this issue quite a bit. Just tested on one timeline instance but it does appear to load if not instantly almost instantly after this setting. Very cool, thank you.

milopersic avatar Aug 11 '22 17:08 milopersic

@TomHiller-swd @milopersic My workaround was to omit options when initializing the timeline, then set options right away.

Before:

const timeline = new vis.Timeline(container, items, options);

After:

const timeline = new vis.Timeline(container, items);
timeline.setOptions(options);

TheophileMot avatar Aug 11 '22 18:08 TheophileMot

Setting the options after timeline initialization does solve the delay issue, but causes some other problems for me when rendering out the data on the timeline. Not sure what's causing that yet, have to play with it a bit. Could just be my configuration.

milopersic avatar Aug 12 '22 15:08 milopersic

I guess this project isn't very active right now, but for anyone else running into this:

  • Range.setRange fires rangeChange immediately. Core sees this and calls _redraw, but the timeline doesn't draw since initialRangeChangeDone is false.
  • Range.setRange waits for 200ms, then sends rangechanged.
  • Core sees rangechanged and sets initialRangeChangeDone to true, but does nothing else.
  • Nothing actually draws until _startAutoResize's watchTimer fires, which has a full second delay.

The fix is probably to redraw in rangechanged like in rangechange, or to set initialRangeChangeDone in rangechange, since you do have a range at that point. But a workaround without changing code is:

    timeline.on("rangechanged", (event, properties) => {
        if(!timeline.initialDrawDone)
            timeline.redraw();
    });

This will still have a 200ms delay before the first draw, so it's better than the full second delay, but it's still unresponsive. I'm not sure why there's a delay before rangechanged, since it would make any UI update look unresponsive. You can force the issue by making sure a range is set, then:

timeline.initialRangeChangeDone = true;
timeline.redraw();

zewt avatar May 23 '23 02:05 zewt