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

[1.x] [Labs] Add useManualCalc prop to TimezonePicker as speed optimization #2564

Merged
merged 4 commits into from
Jun 11, 2018

Conversation

philcchen
Copy link
Contributor

@philcchen philcchen commented Jun 1, 2018

Checklist

  • Include tests
  • Update documentation

Changes proposed in this pull request:

Add a prop to <TimezonePicker> to speed up timezone calculations by skipping moment-timezone parsing of timestamps (slowww). Roughly this has the following performance benefits when turned on

  1. First load of any <TimezonePicker>, ~2x speed improvement
  2. Subsequent load of any <TimezonePicker>, ~5x speed improvement

Reviewers should focus on:

Naming - don't love useManualCalc, happy to rename it to something else/whatever conforms to blueprint naming standards.

Screenshot

useManualCalc: false (current/default behavior)
  • Initial load (127.62ms)
    image
  • Subsequent load (55.89ms)
    image
useManualCalc: true
  • Initial load (57.57ms)
    image
  • Subsequent load (11.23ms)
    image

Suggestions for future optimizations (not planning to do these due to lack of time 🥁 )

  • POSSIBLY BREAKING Set useManualCalc: true by default (maybe 3.x change?). In some preliminary testing, I have yet to find a case where the manual calculation does not match the moment-timezone parsed value
  • getInitialTimezoneItems should use the previously existing timezone items to instead of recalculating timezone items (even though it only does a subset)
  • Factor out the includeLocalTimezone from getInitialTimezoneItems, currently onComponentWillReceiveProps, if only showLocalTimezone changed, it will still re-request all timezones
  • During the filtering of the select, use already calculated timezone metadata instead of recalculating https://github.com/palantir/blueprint/compare/release/1.x...philcchen/use-manual-calc?expand=1#diff-ea00881fc2c40c6d8e0c213ec951ac01R228

@cmslewis cmslewis requested a review from giladgray June 6, 2018 18:03
Copy link
Contributor

@cmslewis cmslewis left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

export function getInitialTimezoneItems(
date: Date,
includeLocalTimezone: boolean,
useManualCalc: boolean,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Worth setting useManualCalc: boolean = false? Then you don't have to update all those tests with the extra param.

return includeLocalTimezone && local !== undefined ? [local, ...populous] : populous;
}

/**
* Get the timezone item for the user's local timezone.
* @param date the date to use when determining timezone offsets
*/
export function getLocalTimezoneItem(date: Date): ITimezoneItem | undefined {
export function getLocalTimezoneItem(date: Date, useManualCalc: boolean): ITimezoneItem | undefined {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same.

@@ -60,6 +60,12 @@ export interface ITimezonePickerProps extends IProps {
*/
showLocalTimezone?: boolean;

/**
* Whether to use manual calculation (faster, but possibly less accurate) rather than moment-timezone to infer metadata;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • typo: Add trailing period, not semicolon.
  • Also, can you add language clarifying what is less accurate when useManualCalc=true?

@@ -209,6 +209,11 @@ describe("<TimezonePicker>", () => {
});
});

it("manual metadata matches moment metadata", () => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👌

Would be helpful to have a test where the two aren't equal (i.e. a "less accurate" case).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@cmslewis had a discussions with @giladgray about possibly removing the forking logic and doing a examination about whether or not it is actually less accurate.

Specifically, I actually don't know of any case where they aren't equal but have not run a comprehensive test checking

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@cmslewis @giladgray wrote up a fiddle here to test, with { +1, 0, +1 } X untils per timezone and tested against all timezones

http://jsfiddle.net/9hnsLgx6/5/

Looks like there are 2338 unique dates, 583 timezones, 1362471 matches, 0 misses.

If this looks good to just replace the logic, I can remove the forking behavior?

@blueprint-bot
Copy link

Remove useManualCalc fork

Preview: documentation | landing | table

Copy link
Contributor

@giladgray giladgray left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@philcchen if you have a sec to make some style tweaks that'd be appreciated!

const index = findOffsetIndex(timestamp, untils);
const abbreviation = getNonOffsetAbbreviation(abbrs[index]);
const offset = offsets[index] * -1;
const offsetAsString = getOffsetAsString(offset);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

slight preference for inlining vars in object def as they're never re-used.

return {
    abbreviation: getNonOffsetAbbreviation(abbrs[index]),
    ...
}

const minutes = offsetVal % 60;
const hours = (offsetVal - minutes) / 60;
const sign = offset >= 0 ? "+" : "-";
return sign + lpad(hours) + ":" + lpad(minutes);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

slight preference for template string.

@blueprint-bot
Copy link

Don't use excess variables and template string

Preview: documentation | landing | table

Copy link
Contributor

@giladgray giladgray left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🚢

@giladgray giladgray merged commit 06f6bbc into release/1.x Jun 11, 2018
@giladgray giladgray deleted the philcchen/use-manual-calc branch June 11, 2018 20:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants