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

perf: add variables caching to v0 #12073

Merged
merged 5 commits into from
Feb 27, 2020
Merged

Conversation

layershifter
Copy link
Member

@layershifter layershifter commented Feb 26, 2020

Pull request checklist

  • Addresses an existing issue: Fixes #0000
  • Include a change request file using $ yarn change

Description of changes

WAT? 😱

This PR adds enableBooleanVariablesCaching which is disabled by default. It allows to handle styles caching for cases when boolean variables are used:

<Provider performance={{ enableBooleanVariablesCaching: true }}>
  <Button variables={{ isFoo: true }} />
</Provider>

Limitations 💔

We use JSON.stringify() for the implementation and it means that boolean variables should go in the same order, i.e. Buttons below will create different cache entries:

<>
  <Button variables={{ isFoo: true, isBar: true }} />
  <Button variables={{ isBar: true, isFoo: true }} />
</>

To avoid this the order should be always the same, proposed solution for customers: enforce the alphabetic order via ESLint rules.

Microsoft Reviewers: Open in CodeFlow

);
});

if (!hasOnlyBooleanVariables) {
Copy link
Contributor

Choose a reason for hiding this comment

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

We should not throw here, we should just not cache for this instance. We are not throwing in the other cases of caching, so we shouldn't here too. We cannot guarantee that all usages of variables are booleans in a project.

Copy link
Member Author

Choose a reason for hiding this comment

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

During offline conversation we discovered issues and I changed the implementation to avoid throwing errors.

@@ -36,7 +36,8 @@ const defaultContext: StylesContextValue<{ renderRule: RendererRenderRule }> = {
performance: {
enableSanitizeCssPlugin: process.env.NODE_ENV !== 'production',
enableStylesCaching: true,
enableVariablesCaching: true
enableVariablesCaching: true,
enableHardVariablesCaching: false
Copy link
Contributor

Choose a reason for hiding this comment

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

Why not enableBooleanVariablesCaching?

Copy link
Member Author

Choose a reason for hiding this comment

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

Renamed, it's definitely sounds better

@size-auditor
Copy link

size-auditor bot commented Feb 26, 2020

Asset size changes

Size Auditor did not detect a change in bundle size for any component!

Baseline commit: fafbe44a2bb89af8aa06496b6f0f9c5d15a2500c (build)

@msft-github-bot
Copy link
Contributor

msft-github-bot commented Feb 26, 2020

Perf Analysis

No significant results to display.

All results

Scenario Master Ticks PR Ticks Status
BaseButton 657 669
BaseButton (experiments) 865 866
DefaultButton 947 944
DefaultButton (experiments) 1761 1716
DetailsRow 3231 3267
DetailsRow (fast icons) 3118 3084
DetailsRow without styles 2952 2906
DocumentCardTitle with truncation 1576 1554
MenuButton 1270 1256
MenuButton (experiments) 3299 3294
PrimaryButton 1075 1056
PrimaryButton (experiments) 1858 1839
SplitButton 2639 2694
SplitButton (experiments) 6628 6618
Stack 413 423
Stack with Intrinsic children 1062 1027
Stack with Text children 3740 3708
Text 355 350
Toggle 756 729
Toggle (experiments) 2090 2091
button 57 61

Perf Analysis (Fluent)

Perf comparison
Status Scenario Fluent TPI Fabric TPI Ratio Iterations Ticks
🔧 Avatar.Fluent 0.56 0.49 1.14:1 2000 1130
🎯 Button.Fluent 0.14 0.2 0.7:1 1000 142
🔧 Checkbox.Fluent 0.9 0.37 2.43:1 1000 900
🔧 Dialog.Fluent 0.36 0.21 1.71:1 5000 1801
🔧 Dropdown.Fluent 3.86 0.46 8.39:1 1000 3857
🔧 Icon.Fluent 0.15 0.05 3:1 5000 736
🦄 Image.Fluent 0.06 0.1 0.6:1 5000 289
🔧 Slider.Fluent 1.51 0.4 3.78:1 1000 1512
🔧 Text.Fluent 0.07 0.02 3.5:1 5000 343
🦄 Tooltip.Fluent 0.12 20.58 0.01:1 5000 585

🔧 Needs work     🎯 On target     🦄 Amazing

All perf tests
Scenario Current PR Ticks Baseline Ticks Ratio
VideoMinimalPerf.default 904 824 1.1:1
AvatarMinimalPerf.default 612 572 1.07:1
ChatWithPopoverPerf.default 646 602 1.07:1
FlexMinimalPerf.default 443 415 1.07:1
FormMinimalPerf.default 895 846 1.06:1
GridMinimalPerf.default 820 772 1.06:1
AttachmentMinimalPerf.default 960 918 1.05:1
ChatMinimalPerf.default 543 519 1.05:1
PortalMinimalPerf.default 285 271 1.05:1
TextMinimalPerf.default 345 330 1.05:1
Avatar.Fluent 1130 1091 1.04:1
Text.Fluent 343 331 1.04:1
BoxMinimalPerf.default 303 294 1.03:1
EmbedMinimalPerf.default 6370 6179 1.03:1
InputMinimalPerf.default 1049 1017 1.03:1
HeaderMinimalPerf.default 525 516 1.02:1
ImageMinimalPerf.default 288 282 1.02:1
LoaderMinimalPerf.default 1072 1051 1.02:1
ProviderMinimalPerf.default 672 661 1.02:1
RefMinimalPerf.default 198 194 1.02:1
TooltipMinimalPerf.default 824 808 1.02:1
Checkbox.Fluent 900 884 1.02:1
CheckboxMinimalPerf.default 4067 4024 1.01:1
DialogMinimalPerf.default 1742 1731 1.01:1
DropdownManyItemsPerf.default 355 352 1.01:1
IconMinimalPerf.default 354 349 1.01:1
ItemLayoutMinimalPerf.default 1985 1965 1.01:1
LabelMinimalPerf.default 1038 1027 1.01:1
ListMinimalPerf.default 400 395 1.01:1
MenuMinimalPerf.default 2093 2073 1.01:1
ReactionMinimalPerf.default 2528 2508 1.01:1
Dialog.Fluent 1801 1788 1.01:1
AlertMinimalPerf.default 602 604 1:1
AnimationMinimalPerf.default 589 588 1:1
AttachmentSlotsPerf.default 3603 3617 1:1
ButtonSlotsPerf.default 699 697 1:1
CarouselMinimalPerf.default 2039 2040 1:1
ChatDuplicateMessagesPerf.default 429 430 1:1
HeaderSlotsPerf.default 1615 1610 1:1
LayoutMinimalPerf.default 632 631 1:1
MenuButtonMinimalPerf.default 1845 1843 1:1
PopupMinimalPerf.default 403 405 1:1
RadioGroupMinimalPerf.default 522 523 1:1
TreeWith60ListItems.default 272 272 1:1
Dropdown.Fluent 3857 3848 1:1
Tooltip.Fluent 585 587 1:1
DividerMinimalPerf.default 935 941 0.99:1
SliderMinimalPerf.default 1500 1517 0.99:1
SplitButtonMinimalPerf.default 12982 13078 0.99:1
TableMinimalPerf.default 658 664 0.99:1
ToolbarMinimalPerf.default 1091 1097 0.99:1
TreeMinimalPerf.default 1122 1130 0.99:1
Button.Fluent 142 144 0.99:1
CustomToolbarPrototype.default 3964 4041 0.98:1
Slider.Fluent 1512 1536 0.98:1
AccordionMinimalPerf.default 221 229 0.97:1
DropdownMinimalPerf.default 3765 3869 0.97:1
HierarchicalTreeMinimalPerf.default 955 984 0.97:1
ListCommonPerf.default 925 953 0.97:1
ProviderMergeThemesPerf.default 1312 1351 0.97:1
Icon.Fluent 736 760 0.97:1
SegmentMinimalPerf.default 1086 1132 0.96:1
TextAreaMinimalPerf.default 3118 3234 0.96:1
Image.Fluent 289 300 0.96:1
ButtonMinimalPerf.default 137 144 0.95:1
StatusMinimalPerf.default 289 303 0.95:1
ListWith60ListItems.default 177 189 0.94:1
ListNestedPerf.default 837 899 0.93:1

? `${displayName}:${JSON.stringify(stylesProps)}${styleParam.rtl}${styleParam.disableAnimations}`
: '';
const propsCacheKey = cacheEnabled ? JSON.stringify(stylesProps) : '';
const variablesCacheKey = cacheEnabled && performance.enableBooleanVariablesCaching ? JSON.stringify(variables) : '';
Copy link
Contributor

Choose a reason for hiding this comment

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

For the props it was not problematic that the props order would change, because we are always mapping them in the same order. On the other hand for the variables we cannot guarantee that, as those are purely users input. I propose to always order them alphabetically and than we can safely use JSON.stringify, or clearly state somewhere that those should always be in the same order...

Copy link
Member Author

Choose a reason for hiding this comment

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

Added this to Limitations section in PR description

expect(() => resolveStyles(options, resolvedVariables)).toThrowError(/Please check your "performance" settings on "Provider"/);
});

test('when enabled only plain objects can be passed as "variables"', () => {
Copy link
Contributor

Choose a reason for hiding this comment

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

Are these last two tests still valid?

Copy link
Member Author

Choose a reason for hiding this comment

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

Yep, I changed their contents and updated titles

@ecraig12345 ecraig12345 added the Fluent UI react-northstar (v0) Work related to Fluent UI V0 label Feb 26, 2020
@layershifter layershifter merged commit af7ffba into master Feb 27, 2020
@layershifter layershifter deleted the feat/styles-hard-variables branch February 27, 2020 09:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Fluent UI react-northstar (v0) Work related to Fluent UI V0
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

6 participants