[@mantine/schedule] Fix O(n²) date re-parsing in WeekView event positioning#9075
Open
eh-bartosz-lewandowski wants to merge 1 commit into
Open
Conversation
…ioning Positioning compared every event against every other and re-parsed dates with dayjs on each comparison — dominated by columnHasConflict recomputing isAllDayEvent across all week days per pair (~1.3M dayjs parses, ~9.6s at 1500 events). Cache parsed start/end timestamps per event via a WeakMap in is-events-overlap, and precompute the all-day flag once when an event is placed into a column (ColumnEvent). Positioning drops from ~9600ms to ~125ms at 1500 events with identical output.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What & why
getWeekPositionedEventsassigns overlapping events to columns in an O(n²) pass, and on every pairwise comparison it re-parsed dates with dayjs —isEventsOverlapparsed all four start/end strings, andcolumnHasConflictrecomputed each event's all-day flag by callingisAllDayEventacross every weekday. At ~1,500 events that is ~1.3M dayjs parses ≈ 9.6s to lay out one week, and it degrades quadratically.Change
Parse each date once instead of on every comparison:
{ start, end }timestamps in aWeakMapinis-events-overlap(also benefits DayView / ResourcesDayView, which use the same util).ColumnEvent { event, allDay }, socolumnHasConflictreads the precomputed flag instead of recomputingisAllDayEvent.This is a pure memoization / precompute — layout output is unchanged. The stored per-event all-day flag is equivalent to the original per-comparison recompute:
isAllDayEventis true only on the event's own start day, which is always within the event's covered days.Result
Positioning 1,500 events: ~9,600ms → ~125ms (~77×); a typical week lays out in a few ms.
Notes
The
WeakMapassumes events are immutable value objects (matching the library's callback-based update model). Mutating an existing event'sstart/endin place while reusing the same object reference across positioning passes would serve cached timestamps — not a concern for normal usage.Tests
Updated
find-available-columnunit tests for the new column shape.