Please see the following docs topic for Scheduler scrolling performance tuning options:
https://doc.daypilot.org/scheduler/scrolling-performance/
It's necessary to keep the total DOM size as small as possible. Most browsers will start to show performance problems when the page size reaches 5,000-10,000 objects (even on powerful machines). It affects page loading speed, memory consumption and scrolling performance.
The Scheduler includes optimizations to address this problem. By default, progressive rendering is enabled (https://doc.daypilot.org/scheduler/progressive-event-rendering/). In this mode, the Scheduler only renders the events for the visible viewport (Scheduler viewport, not browser viewport). Just make sure that your Scheduler limits its viewport to the screen (e.g. set viewType to "Max", "Parent100Pct" or other option instead of the default "Auto").
If you display really large data sets you can switch to dynamic event loading. This mode loads the required events from the server during scrolling. It brings a small delay before the events are rendered for the new location but the performance is stable (it scales really well). See the following tutorial:
https://code.daypilot.org/15036/angular-scheduler-dynamic-loading-of-large-data-sets
The static event rendering turns off this optimization and is not recommended.
The non-passive scroll event listener is necessary for synchronization of the frozen headers. However, the Scheduler debounces all UI updates using "scrollDelay*" properties. This way you can keep the scrolling smooth (see more at https://doc.daypilot.org/scheduler/scrolling-performance/).
Also, in Angular applications with lots of events it's necessary to switch to the direct API for loading events. The automatic change detection that is used to check the [events] attribute is convenient but it brings overhead. See more details here:
https://doc.daypilot.org/scheduler/angular/