Skip to content

[scheduler] Recompute nowUpdatedEveryMinute only on timezone change#22793

Merged
rita-codes merged 2 commits into
mui:masterfrom
Anexus5919:fix/scheduler-now-recompute-on-timezone-change
Jun 12, 2026
Merged

[scheduler] Recompute nowUpdatedEveryMinute only on timezone change#22793
rita-codes merged 2 commits into
mui:masterfrom
Anexus5919:fix/scheduler-now-recompute-on-timezone-change

Conversation

@Anexus5919

Copy link
Copy Markdown
Contributor

Closes #22765

Summary

SchedulerStore.updateStateFromParameters reassigned nowUpdatedEveryMinute = adapter.now(...) on every parameter change. adapter.now() returns a fresh object reference each call, so any prop change (view, visibleDate, events, and so on) gave now a new reference, even when nothing time related changed. This PR makes that recompute conditional on a real displayTimezone change, leaving the once per minute timer as the sole owner of the periodic refresh.

Root cause

The store already maintains nowUpdatedEveryMinute with a minute aligned timer set up in the constructor. The unconditional line in updateStateFromParameters fought that design: it ran on essentially every render, because the three calling hooks (useEventCalendar, useEventCalendarPremium, useEventTimelinePremium) invoke updateStateFromParameters from a layout effect keyed on the whole parameters object.

The user visible cost is wasted re-renders. The schedulerNowSelectors.nowUpdatedEveryMinute selector is a pass through whose output is the now reference itself. base-ui's useStore compares each selector output with Object.is, so a new reference forces a re-render of every current time consumer (the current time indicator, agenda view, mini calendar, and day time grid) on changes that have nothing to do with time.

Changes

packages/x-scheduler-internals/src/internals/utils/SchedulerStore/SchedulerStore.ts

// Recompute "now" only when the display timezone changes; the minute timer maintains it otherwise.
if (newSchedulerState.displayTimezone !== this.state.displayTimezone) {
  newSchedulerState.nowUpdatedEveryMinute =
    adapter.now(newSchedulerState.displayTimezone!);
}

This is safe because Store.update() is a shallow merge: omitting nowUpdatedEveryMinute from the partial preserves the existing reference. The comparison reads the previous this.state.displayTimezone, since update() runs afterward. Recomputing on a genuine timezone change stays correct, because now is timezone stamped and would otherwise show the wrong wall clock until the next minute tick.

The fix lives in the base SchedulerStore, so all store variants (Event Calendar, Event Calendar Premium, Event Timeline Premium) benefit through the one change.

Alternative considered

Also guarding on adapter !== this.state.adapter was considered and rejected. The adapter only changes identity when dateLocale changes, and the date-fns adapter's comparison methods (now, isSameDay, isBefore, isEqual) take no locale argument, so a now value stays valid across a locale change. Adding that guard would reintroduce a slice of the churn for no correctness benefit.

Tests

Added two cases to core.SchedulerStore.test.ts, in the existing updater block, which run across all store classes via storeClasses.forEach:

  1. nowUpdatedEveryMinute keeps the same reference when a non-timezone parameter changes.
  2. nowUpdatedEveryMinute is recomputed, and correctly zoned, when displayTimezone changes.

Reverting the fix makes the first test fail with a reference inequality across all three store classes, confirming the test catches the regression.

Verification run locally: full x-scheduler-internals suite (790 passed, 3 skipped), full x-scheduler-internals-premium suite (443 passed), TypeScript clean for @mui/x-scheduler-internals, ESLint clean, Prettier clean.

Changelog

@mui/x-scheduler

  • Avoid resetting the scheduler's "now" value (and the unnecessary re-renders it caused) on parameter changes that do not change the display timezone.

  • I have followed (at least) the PR section of the contributing guide.

@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.
To continue using code reviews, you can upgrade your account or add credits to your account and enable them for code reviews in your settings.

@Anexus5919

Copy link
Copy Markdown
Contributor Author

@rita-codes @zannager Kindly have a review on this whenever you get time. Thanks!

@code-infra-dashboard

code-infra-dashboard Bot commented Jun 12, 2026

Copy link
Copy Markdown

Deploy preview

https://deploy-preview-22793--material-ui-x.netlify.app/

Bundle size

Bundle Parsed size Gzip size
@mui/x-data-grid 0B(0.00%) 0B(0.00%)
@mui/x-data-grid-pro 0B(0.00%) 0B(0.00%)
@mui/x-data-grid-premium 0B(0.00%) 0B(0.00%)
@mui/x-charts 0B(0.00%) 0B(0.00%)
@mui/x-charts-pro 0B(0.00%) 0B(0.00%)
@mui/x-charts-premium 0B(0.00%) 0B(0.00%)
@mui/x-date-pickers 0B(0.00%) 0B(0.00%)
@mui/x-date-pickers-pro 0B(0.00%) 0B(0.00%)
@mui/x-tree-view 0B(0.00%) 0B(0.00%)
@mui/x-tree-view-pro 0B(0.00%) 0B(0.00%)
@mui/x-license 0B(0.00%) 0B(0.00%)

Details of bundle changes


Check out the code infra dashboard for more information about this PR.

@zannager zannager added the scope: scheduler Changes related to the scheduler. label Jun 12, 2026
@rita-codes rita-codes added the type: enhancement It’s an improvement, but we can’t make up our mind whether it's a bug fix or a new feature. label Jun 12, 2026
@rita-codes

Copy link
Copy Markdown
Member

Approach looks right to me! Tests across all three store classes are good coverage 🙌

Thanks for fixing this! 🙇

@rita-codes rita-codes changed the title [scheduler] Recompute nowUpdatedEveryMinute only on timezone change [scheduler] Recompute nowUpdatedEveryMinute only on timezone change Jun 12, 2026
@rita-codes
rita-codes merged commit 7540858 into mui:master Jun 12, 2026
24 checks passed
mbrookes pushed a commit to mbrookes/mui-x that referenced this pull request Jun 27, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

scope: scheduler Changes related to the scheduler. type: enhancement It’s an improvement, but we can’t make up our mind whether it's a bug fix or a new feature.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[scheduler] nowUpdatedEveryMinute reset on every parameter change (only needed on timezone change)

3 participants