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

ngbDatePicker does some super eager processing/optimisation around min and max dates which can result in it hanging the browser.. #3338

Closed
simon-tamman opened this issue Aug 23, 2019 · 2 comments · Fixed by #3357

Comments

@simon-tamman
Copy link

simon-tamman commented Aug 23, 2019

Now careful, opening the datepicker in this sample will blow your browser (you'll hang and maybe it will chew up all your memory).

StackBlitz.

To fix it again just make min/max date a "sensible" window. What's breaking it is the line:

maxDate = {year:99999, month:1, day:1}

in datepicker.popup.ts.
FWIW, the maximum possible date in javascript is something like year ~200,000 (if you convert from new Date(8640000000000000)) so it can be even worse than this (guess which value I was using first when I discovered this issue :S). So this basically means if you say to the ngbDatePicker:

don't restrict selection at all

By specifying a ridiculously maximum possible range, it will just chew all of your resources until it dies or you're actually patient enough for it to finish.
Obviously we can work around this issue by adding extra validation on min/max prior to hitting this component by enforcing a range ourselves but then we have to make the executive decision of what constitutes a "sensible" date range (so Doctor Who will not be able to use our software given his silly time-travelling hi-jinks).
This is irksome in the use-cases I'm working with mostly because the min/maxes in other areas are dynamic and without the custom protection someone could break the system by entering a 'silly' date in a subsystem elsewhere. It would be neater if the component itself handled silly min/maxes more sensibly/suspiciously instead of being so eager and earnest.

At a guess I'd suggest the core issue is some sort of eager processing and/or optimisation around the displaying of the date picker, instead of only processing what it needs to at a given point in time it processes everything it might need upfront. When you open the date picker all you should need is the current month (or maybe just the nearest +12/-12 months and a list of integers for every year, sure that's potentially over 200,000 numbers but I don't think that should explain the enormity of the current behaviour.
FWIW, I've had it perform even worse when working in timezones outside of UTC+0 and UTC+11 within the application I'm working in so its possible there's a further inefficiency somewhere that amplifies its impact. Also in my experience its much worse in Edge/Firefox than it is Chrome, however these extra notes were observed under the taint of our application and may not apply to this core library.

Versions of Angular, ng-bootstrap and Bootstrap:

Angular: 8.2.3

ng-bootstrap: 5.0.0

Bootstrap: 4.3.1 (I think?)

As this is the first issue I've submitted here I apologise if I've broken any etiquette.
Otherwise its been relatively pleasant working with this component (after I got my head around dates in javascript), so thank you for these libraries, the work is massively appreciated. <3

@simon-tamman simon-tamman changed the title ngbDatePicker does some super eager processing/optimisation around min and max dates. ngbDatePicker does some super eager processing/optimisation around min and max dates which can result in it hanging the browser.. Aug 23, 2019
@maxokorokov maxokorokov self-assigned this Sep 3, 2019
@maxokorokov maxokorokov added this to the 5.1.2 milestone Sep 3, 2019
@maxokorokov
Copy link
Member

@simon-tamman thanks for the reporting this. True that it is an edge case and it's probably up to you to pre-filter the min/max dates before giving them to the datepicker.

However, the issue was with generating select box year values. It was literally trying to generate 200000+ options inside the select box.

At the moment the best solution I came up with is to limit to 1000 elements in the select box max, rendering. Anyway if you need more, most likely you shouldn't use select boxes.

@simon-tamman
Copy link
Author

Much love <3

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment