angular-slider / ngx-slider

Self-contained, mobile friendly slider component for Angular based on angularjs-slider
https://angular-slider.github.io/ngx-slider/
MIT License
388 stars 175 forks source link

Rendering Performance #45

Open rs200x opened 5 years ago

rs200x commented 5 years ago

Hi,

I have a view where I have to display 480 sliders (120 rows with 4 sliders each). Once the view is rendered it looks nice and every slider can be used without any delay. But the rendering process takes als 5-7 seconds, which is not really acceptable.

In the console log I see again some violation issues:

[Violation] 'message' handler took 5208ms
[Violation] Forced reflow while executing JavaScript took 4087ms
---
[Violation] 'click' handler took 11076ms
[Violation] Forced reflow while executing JavaScript took 6416ms
[Violation] 'resize' handler took 15084ms
[Violation] Forced reflow while executing JavaScript took 2992ms

image

As I need only a simple layout, I already tried to disable all possible options. 2018-12-05 11_50_01-bidib-toolbox

  defaultOptions: Options = {
    floor: 0,
    ceil: 255,
    step: 1,
    noSwitching: true,
    hideLimitLabels: true,
    hidePointerLabels: true,
    showOuterSelectionBars: false,
    showSelectionBarEnd: false,
    showSelectionBar: false,
    showTicksValues: false
  };

Is there more I can tweak?

piotrdz commented 5 years ago

The problem in this case is that initial render of the slider is always going to be slow, as a result of the design.

The slider can't set the positions and styles of its sub-elements until it knows the dimensions of its container in the DOM. So the slider waits until it is rendered for the first time, and then initialises itself, adjusting the styles of its sub-elements as necessary. This is also complicated somewhat by Angular, because once the view has changed (again), Angular change detection kicks in, re-checking all the bindings.

I would also say that 480 dynamic elements on a page, be it sliders or something else, is already quite a lot to handle for the browser. I think you are going to see performance issues no matter what component you use.

rs200x commented 5 years ago

I expected something like this and can understand the background.

The thing is, if I switch to the standard input type=range elements, it's loading/rendering the page within 400-600ms, which is absolutely acceptable. image

With this I only need the ng5 slider for the 'real' range mode, which is ok if I just need the basic style.

As you can see I just need the basic elements. Is there maybe an option (with some triggers) to reduce the layout/DOM elements to decide between functionality and performance?

piotrdz commented 5 years ago

No, I'm afraid it's all or nothing at the moment. The time it takes for each slider to initialise itself and apply all the styles just adds up.

Now, there might be a way to improve it, by cutting out some of Angular's overhead, and possibly skipping some initialisation steps when they are not needed. But to do that, I'll need to profile the code and I'll see what I can do.

rs200x commented 5 years ago

Don't worry and take your time. I found a solution, which I would call intermediate. If you can do some improvements, I would appreciate it. If not, I can live with that, too.

jhinzmann commented 5 years ago

Don't worry and take your time. I found a solution, which I would call intermediate. If you can do some improvements, I would appreciate it. If not, I can live with that, too.

I've got a similar problem with the slider. Each slider calls getBoundingClientRect which forces a reflow on init. When multiple sliders are added at once, this leads to layout thrashing. Maybe it would be an option to provide the needed dimensions via optional input?

@rs200x Could you describe your solution to this problem?

rs200x commented 5 years ago

@jhinzmann my solution is to use the stand input type=range and just to use the ng5 slider for the double range items.

But there I also have some rendering problems: image (left and right is input, middle ng5-slider)

Once I click on one of them, the all markers get placed correctly.

jhinzmann commented 5 years ago

@rs200x the set of features that you use for the slider (no labels, same width for a lot of sliders) actually are quite similar to the set I use in my setup.

I opened a pull request (#59) that should improve the performance for this kind of setups. Maybe you could checkout my branch and build the ng5-slider locally to test it with your setup? It would be nice to get some feedback on your results with this new version.

piotrdz commented 5 years ago

Changes from @jhinzmann's pull request is now available in v1.1.12.