-
Notifications
You must be signed in to change notification settings - Fork 0
Fix timezone performance bottleneck with intelligent year-based caching and localStorage persistence #163
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
Fix timezone performance bottleneck with intelligent year-based caching and localStorage persistence #163
Changes from 7 commits
baf4b2b
3770044
1cdb60a
b2351a0
4c13eae
26d406c
358b5f1
8573733
958067b
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -1233,29 +1233,61 @@ interface WindowWithTimeline extends Window { | |||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| (window as WindowWithTimeline).initializeTimeline = initializeTimeline; | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| // Cache for processed timezone data to avoid expensive recalculations | ||||||||||||||||||||||||||||||||||
| interface ProcessedTimezoneData { | ||||||||||||||||||||||||||||||||||
| julyTimeZones: TimeZone[]; | ||||||||||||||||||||||||||||||||||
| decemberTimeZones: TimeZone[]; | ||||||||||||||||||||||||||||||||||
| userTimezone: string; | ||||||||||||||||||||||||||||||||||
| currentYear: number; | ||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| // Cache for timezone data by year to avoid expensive recalculations | ||||||||||||||||||||||||||||||||||
| const processedTimezoneCache = new Map<number, ProcessedTimezoneData>(); | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| /** | ||||||||||||||||||||||||||||||||||
| * Get all supported timezones that the browser knows about, | ||||||||||||||||||||||||||||||||||
| * ordered starting with the user's current timezone and going around the world | ||||||||||||||||||||||||||||||||||
| * @param date Optional date to calculate timezone offsets for (defaults to current date) | ||||||||||||||||||||||||||||||||||
| * @returns Array of timezone objects ordered from user's timezone around the globe | ||||||||||||||||||||||||||||||||||
| * Initialize timezone data by processing all browser timezones for July and December | ||||||||||||||||||||||||||||||||||
| * This expensive operation should only be done once on page load | ||||||||||||||||||||||||||||||||||
| */ | ||||||||||||||||||||||||||||||||||
| export function getAllTimezonesOrdered(date?: Date): TimeZone[] { | ||||||||||||||||||||||||||||||||||
| // Get user's timezone using Temporal (polyfill ensures availability) | ||||||||||||||||||||||||||||||||||
| function initializeTimezoneData(year: number = new Date().getFullYear()): ProcessedTimezoneData { | ||||||||||||||||||||||||||||||||||
| const userTimezone = Temporal.Now.timeZoneId(); | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| const now = date || new Date(); | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| // Get all supported timezones (comprehensive list) | ||||||||||||||||||||||||||||||||||
| const allTimezones = Intl.supportedValuesOf('timeZone'); | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| // Create timezone objects with current offsets using Intl (proven compatibility) | ||||||||||||||||||||||||||||||||||
| const timezoneData = allTimezones.map(iana => { | ||||||||||||||||||||||||||||||||||
| // Create dates for July 1st and December 31st to capture DST variations | ||||||||||||||||||||||||||||||||||
| const julyDate = new Date(year, 6, 1); // July 1st | ||||||||||||||||||||||||||||||||||
| const decemberDate = new Date(year, 11, 31); // December 31st | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| console.log(`Processing ${allTimezones.length} timezones for July and December variants...`); | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| // Process timezones for July (typically DST active in Northern Hemisphere) | ||||||||||||||||||||||||||||||||||
| const julyTimeZones = processTimezonesForDate(allTimezones, julyDate, userTimezone); | ||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||
| // Create dates for July 1st and December 31st to capture DST variations | |
| const julyDate = new Date(year, 6, 1); // July 1st | |
| const decemberDate = new Date(year, 11, 31); // December 31st | |
| console.log(`Processing ${allTimezones.length} timezones for July and December variants...`); | |
| // Process timezones for July (typically DST active in Northern Hemisphere) | |
| const julyTimeZones = processTimezonesForDate(allTimezones, julyDate, userTimezone); | |
| // Create dates for June 1st and December 31st to capture DST variations | |
| const juneDate = new Date(year, 5, 1); // June 1st | |
| const decemberDate = new Date(year, 11, 31); // December 31st | |
| console.log(`Processing ${allTimezones.length} timezones for July and December variants...`); | |
| // Process timezones for June (typically DST active in Northern Hemisphere) | |
| const juneTimeZones = processTimezonesForDate(allTimezones, juneDate, userTimezone); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There's an inconsistency between the July date creation (July 1st) and the later comment mentioning June 1st for summer time calculations. The getTimezoneVariations function uses June 1st while the new code uses July 1st. This inconsistency could lead to different DST calculations.
@copilot lots of inconsistencies here.
Outdated
Copilot
AI
Aug 9, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The documentation is inconsistent - it mentions 'July (June 1st)' which is confusing. It should either say 'July (July 1st)' to match the new caching implementation or 'Summer (June 1st)' to match the actual implementation in this function.
| * Returns both July (June 1st) and December (December 31st) variations | |
| * Returns both summer (June 1st) and winter (December 31st) variations |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The documentation is inconsistent - it mentions 'July (June 1st)' which is confusing. It should either say 'July (July 1st)' to match the new caching implementation or 'Summer (June 1st)' to match the actual implementation in this function.
@copilot please ensure we're using June 1st everywhere and that we rename the variables and comments appropriately
Outdated
Copilot
AI
Aug 9, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The comment is misleading as it mentions 'June 1st for July time' but the code actually uses June 1st (summerDate) for summer calculations. The comment should be updated to accurately reflect the dates being used or the variable names should be updated to match the comment.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The comment is misleading as it mentions 'June 1st for July time' but the code actually uses June 1st (summerDate) for summer calculations. The comment should be updated to accurately reflect the dates being used or the variable names should be updated to match the comment.
@copilot please address
Uh oh!
There was an error while loading. Please reload this page.